From 5ad579ad780ea272cc31dcabd8002130b7d0389c Mon Sep 17 00:00:00 2001 From: Hparty <420024556@qq.com> Date: Fri, 6 Dec 2024 21:20:46 +0800 Subject: [PATCH] =?UTF-8?q?Update=20tgfx=20to=20the=20latest=20version?= =?UTF-8?q?=E3=80=82?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- CMakeLists.txt | 4 +- DEPS | 2 +- src/platform/web/PAGWasmBindings.cpp | 58 +++++++++++++++++---- web/cypress/integration/pag-surface.spec.ts | 10 ++-- web/src/pag-file.ts | 6 +-- web/src/pag-image.ts | 5 +- web/src/pag-surface.ts | 4 +- web/src/types.ts | 4 +- web/src/utils/buffer.ts | 33 ++++++++++++ 9 files changed, 97 insertions(+), 29 deletions(-) create mode 100644 web/src/utils/buffer.ts diff --git a/CMakeLists.txt b/CMakeLists.txt index e989e4546e..c00116c93e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -493,10 +493,10 @@ if (WEB) -sMODULARIZE=1 -sENVIRONMENT='web,worker' -sEXPORT_ES6=1 -sUSE_ES6_IMPORT_META=0) if (CMAKE_BUILD_TYPE STREQUAL "Debug") list(APPEND PAG_COMPILE_OPTIONS -O0 -g3) - list(APPEND PAG_LINK_OPTIONS -O0 -g3 -sSAFE_HEAP=1 -Wno-limited-postlink-optimizations) + list(APPEND PAG_LINK_OPTIONS -O0 -g3 -sSAFE_HEAP=1 -Wno-limited-postlink-optimizations -s EXPORTED_FUNCTIONS=['_malloc','_free']) else () list(APPEND PAG_COMPILE_OPTIONS -Oz) - list(APPEND PAG_LINK_OPTIONS -Oz) + list(APPEND PAG_LINK_OPTIONS -Oz -s EXPORTED_FUNCTIONS=['_malloc','_free']) endif () elseif (PAG_BUILD_SHARED) add_library(pag SHARED ${PAG_FILES}) diff --git a/DEPS b/DEPS index 2c60c7d4e5..69f5fb91de 100644 --- a/DEPS +++ b/DEPS @@ -12,7 +12,7 @@ }, { "url": "${PAG_GROUP}/tgfx.git", - "commit": "0ee494ab8246bb051e66b4681832ebcac18b8e39", + "commit": "bc72a3730fe0733391dbaf5ce8ec139a8073c1a6", "dir": "third_party/tgfx" }, { diff --git a/src/platform/web/PAGWasmBindings.cpp b/src/platform/web/PAGWasmBindings.cpp index 4fcb431eec..813f6ec89b 100644 --- a/src/platform/web/PAGWasmBindings.cpp +++ b/src/platform/web/PAGWasmBindings.cpp @@ -31,6 +31,26 @@ using namespace emscripten; namespace pag { + +std::unique_ptr CopyDataFromUint8Array(const val& emscriptenData) { + if (!emscriptenData.as()) { + return nullptr; + } + auto length = emscriptenData["length"].as(); + if (length == 0) { + return nullptr; + } + auto buffer = ByteData::Make(length); + if (!buffer) { + return nullptr; + } + auto memory = val::module_property("HEAPU8")["buffer"]; + auto memoryView = + val::global("Uint8Array").new_(memory, reinterpret_cast(buffer->data()), length); + memoryView.call("set", emscriptenData); + return buffer; +} + bool PAGBindInit() { class_("_PAGLayer") .smart_ptr>("_PAGLayer") @@ -215,8 +235,13 @@ bool PAGBindInit() { class_>("_PAGFile") .smart_ptr>("_PAGFile") .class_function("_MaxSupportedTagLevel", PAGFile::MaxSupportedTagLevel) - .class_function("_Load", optional_override([](uintptr_t bytes, size_t length) { - return PAGFile::Load(reinterpret_cast(bytes), length); + .class_function("_Load", + optional_override([](const val& emscriptenData) -> std::shared_ptr { + auto data = CopyDataFromUint8Array(emscriptenData); + if (data == nullptr) { + return nullptr; + } + return PAGFile::Load(data->data(), data->length()); })) .function("_tagLevel", &PAGFile::tagLevel) .function("_numTexts", &PAGFile::numTexts) @@ -284,20 +309,31 @@ bool PAGBindInit() { class_("_PAGImage") .smart_ptr>("_PAGImage") - .class_function("_FromBytes", optional_override([](uintptr_t bytes, size_t length) { - return PAGImage::FromBytes(reinterpret_cast(bytes), length); + .class_function("_FromBytes", + optional_override([](const val& emscriptenData) -> std::shared_ptr { + auto data = CopyDataFromUint8Array(emscriptenData); + if (data == nullptr) { + return nullptr; + } + return PAGImage::FromBytes(reinterpret_cast(data->data()), + data->length()); })) .class_function("_FromNativeImage", optional_override([](val nativeImage) { auto image = tgfx::Image::MakeFrom(nativeImage); return std::static_pointer_cast(StillImage::MakeFrom(image)); })) - .class_function("_FromPixels", - optional_override([](uintptr_t pixels, int width, int height, size_t rowBytes, - int colorType, int alphaType) { - return PAGImage::FromPixels(reinterpret_cast(pixels), width, height, - rowBytes, static_cast(colorType), - static_cast(alphaType)); - })) + .class_function( + "_FromPixels", + optional_override([](const val& pixels, int width, int height, size_t rowBytes, + int colorType, int alphaType) -> std::shared_ptr { + auto data = CopyDataFromUint8Array(pixels); + if (data == nullptr) { + return nullptr; + } + return PAGImage::FromPixels(reinterpret_cast(data->data()), width, height, + rowBytes, static_cast(colorType), + static_cast(alphaType)); + })) .class_function("_FromTexture", optional_override([](int textureID, int width, int height, bool flipY) { GLTextureInfo glInfo = {}; diff --git a/web/cypress/integration/pag-surface.spec.ts b/web/cypress/integration/pag-surface.spec.ts index 68f75dbeb3..6f6f3bb58d 100644 --- a/web/cypress/integration/pag-surface.spec.ts +++ b/web/cypress/integration/pag-surface.spec.ts @@ -61,8 +61,12 @@ describe('PAGSurface', () => { pagPlayer.setProgress(0.5); pagPlayer.setScaleMode(PAGTypes.PAGScaleMode.Stretch); await pagPlayer.flush(); - expect(pagSurface.readPixels(PAGTypes.ColorType.RGBA_8888, PAGTypes.AlphaType.Unpremultiplied).byteLength).to.be.eq( - 360000, - ); + console.log("readPixels"); + const tmp = pagSurface.readPixels(PAGTypes.ColorType.RGBA_8888, PAGTypes.AlphaType.Unpremultiplied); + console.log(tmp); + expect(tmp.byteLength).to.be.eq(360000); + // expect(pagSurface.readPixels(PAGTypes.ColorType.RGBA_8888, PAGTypes.AlphaType.Unpremultiplied).byteLength).to.be.eq( + // 360000, + // ); }); }); diff --git a/web/src/pag-file.ts b/web/src/pag-file.ts index 2b6c8d8b0a..5c26247cbe 100644 --- a/web/src/pag-file.ts +++ b/web/src/pag-file.ts @@ -6,7 +6,6 @@ import { getLayerTypeName, layer2typeLayer, proxyVector } from './utils/type-uti import type { PAGImage } from './pag-image'; import { LayerType, PAGTimeStretchMode, TextDocument } from './types'; -import { writeBufferToWasm } from '@tgfx/utils/buffer'; @destroyVerify @wasmAwaitRewind @@ -28,9 +27,8 @@ export class PAGFile extends PAGComposition { */ public static loadFromBuffer(buffer: ArrayBuffer) { if (!buffer || !(buffer.byteLength > 0)) throw new Error('Initialize PAGFile data not be empty!'); - const { byteOffset, length, free } = writeBufferToWasm(PAGModule, buffer); - const wasmIns = PAGModule._PAGFile._Load(byteOffset, length); - free(); + const uint8Buffer = new Uint8Array(buffer); + const wasmIns = PAGModule._PAGFile._Load(uint8Buffer); if (!wasmIns) throw new Error('Load PAGFile fail!'); const pagFile = new PAGFile(wasmIns); return pagFile; diff --git a/web/src/pag-image.ts b/web/src/pag-image.ts index cf44bb6193..45812f2b7f 100644 --- a/web/src/pag-image.ts +++ b/web/src/pag-image.ts @@ -2,7 +2,6 @@ import { AlphaType, ColorType, PAGScaleMode } from './types'; import { wasmAwaitRewind, wasmAsyncMethod, destroyVerify } from './utils/decorators'; import { PAGModule } from './pag-module'; import { Matrix } from './core/matrix'; -import { writeBufferToWasm } from '@tgfx/utils/buffer'; @destroyVerify @wasmAwaitRewind @@ -49,9 +48,7 @@ export class PAGImage { alphaType: AlphaType, ): PAGImage { const rowBytes = width * (colorType === ColorType.ALPHA_8 ? 1 : 4); - const { byteOffset, free } = writeBufferToWasm(PAGModule, pixels); - const wasmIns = PAGModule._PAGImage._FromPixels(byteOffset, width, height, rowBytes, colorType, alphaType); - free(); + const wasmIns = PAGModule._PAGImage._FromPixels(pixels, width, height, rowBytes, colorType, alphaType); if (!wasmIns) throw new Error('Make PAGImage from pixels fail!'); return new PAGImage(wasmIns); } diff --git a/web/src/pag-surface.ts b/web/src/pag-surface.ts index a66c9f8b64..cc2397224b 100644 --- a/web/src/pag-surface.ts +++ b/web/src/pag-surface.ts @@ -1,6 +1,6 @@ import { PAGModule } from './pag-module'; import { AlphaType, ColorType } from './types'; -import { readBufferFromWasm } from '@tgfx/utils/buffer'; +import { readBufferFromWasm } from './utils/buffer'; import { destroyVerify, wasmAwaitRewind } from './utils/decorators'; @destroyVerify @@ -76,7 +76,7 @@ export class PAGSurface { if (colorType === ColorType.Unknown) return null; const rowBytes = this.width() * (colorType === ColorType.ALPHA_8 ? 1 : 4); const length = rowBytes * this.height(); - const dataUint8Array = new Uint8Array(length); + const dataUint8Array = new Uint8Array(PAGModule.HEAPU8.buffer, length); const { data, free } = readBufferFromWasm(PAGModule, dataUint8Array, (dataPtr) => { return this.wasmIns._readPixels(colorType, alphaType, dataPtr, rowBytes) as boolean; }); diff --git a/web/src/types.ts b/web/src/types.ts index c6c79120b7..9a57110c1a 100644 --- a/web/src/types.ts +++ b/web/src/types.ts @@ -31,13 +31,13 @@ declare global { export interface PAG extends EmscriptenModule { _PAGFile: { - _Load: (bytes: number, length: number) => any; + _Load: (buffer: Uint8Array) => any; _MaxSupportedTagLevel: () => number; }; _PAGImage: { _FromNativeImage: (source: TexImageSource | ArrayBufferImage) => any; _FromPixels: ( - pixels: number, + pixels: Uint8Array, width: number, height: number, rowBytes: number, diff --git a/web/src/utils/buffer.ts b/web/src/utils/buffer.ts new file mode 100644 index 0000000000..93c1653639 --- /dev/null +++ b/web/src/utils/buffer.ts @@ -0,0 +1,33 @@ +///////////////////////////////////////////////////////////////////////////////////////////////// +// +// Tencent is pleased to support the open source community by making tgfx available. +// +// Copyright (C) 2024 THL A29 Limited, a Tencent company. All rights reserved. +// +// Licensed under the BSD 3-Clause License (the "License"); you may not use this file except +// in compliance with the License. You may obtain a copy of the License at +// +// https://opensource.org/licenses/BSD-3-Clause +// +// unless required by applicable law or agreed to in writing, software distributed under the +// license is distributed on an "as is" basis, without warranties or conditions of any kind, +// either express or implied. see the license for the specific language governing permissions +// and limitations under the license. +// +///////////////////////////////////////////////////////////////////////////////////////////////// + +export const readBufferFromWasm = ( + module: EmscriptenModule, + data: ArrayLike | ArrayBufferLike, + handle: (byteOffset: number, length: number) => boolean, +) => { + const uint8Array = new Uint8Array(data); + const dataPtr = module._malloc(uint8Array.byteLength); + if (!handle(dataPtr, uint8Array.byteLength)) return { + data: null, + free: () => module._free(dataPtr) + }; + const dataOnHeap = new Uint8Array(module.HEAPU8.buffer, dataPtr, uint8Array.byteLength); + uint8Array.set(dataOnHeap); + return {data: uint8Array, free: () => module._free(dataPtr)}; +};