Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix the label black border on the native platform. #130

Conversation

Projects
None yet
4 participants
@caryliu1999
Copy link
Contributor

commented Apr 19, 2019

Re: cocos-creator/2d-tasks#1210

修复说明见Task.

@@ -53,8 +58,10 @@ class HTMLCanvasElement extends HTMLElement {
this._data = new ImageData(this._width, this._height);
this._context2D._canvas = this;
this._context2D._setCanvasBufferUpdatedCallback(function (data) {
// Because the blend factor is modified to SRC_ALPHA, here must perform unpremult alpha.

This comment has been minimized.

Copy link
@2youyou2

2youyou2 Apr 19, 2019

Contributor

这个 callback 的调用时机是什么样的,如果连续多次调用下面的代码,这个回调会调用几次?

_context.strokeText
_context.fillText
_context.strokeText
_context.fillText

This comment has been minimized.

Copy link
@caryliu1999

caryliu1999 Apr 19, 2019

Author Contributor

这个 callback 的调用时机是什么样的,如果连续多次调用下面的代码,这个回调会调用几次?

_context.strokeText
_context.fillText
_context.strokeText
_context.fillText

发生绘制的情况下就会回调,fillRect, fillText, strokeText都会调用,因为每次绘制相当于bitmap的数据发生了改变,都需要同步更新到js层缓存的像素数据。

This comment has been minimized.

Copy link
@caryliu1999

caryliu1999 Apr 19, 2019

Author Contributor

这里得考虑下如何规避array buffer的重复创建

This comment has been minimized.

Copy link
@jareguo

jareguo Apr 20, 2019

Contributor

这里要 new Uint8ClampedArray 的次数有点多了,不能直接改 data 本身吗?

This comment has been minimized.

Copy link
@2youyou2

2youyou2 Apr 22, 2019

Contributor

fillRect, fillText, strokeText都会调用

这个消耗就有点大了。。这些函数调用的频率在 _updateTexture 里非常大

var temp = new Uint8ClampedArray(w * h * 4);
var alpha = 0;
for (let i = 0, len = data.length / 4; i < len; i++) {
alpha = data[i * 4 + 3];

This comment has been minimized.

Copy link
@jareguo

jareguo Apr 20, 2019

Contributor

i *4 的次数太多了,建议直接 for (let i = 0, len = data.length; i < len; i+=4) {

@jareguo

This comment has been minimized.

Copy link
Contributor

commented Apr 20, 2019

我觉得这个修复方法对 js 性能太不友好了,原生平台的问题应该尽量在原生平台修复才对,这本来就是底层应该抹平的平台差异。
原生平台返回 BitMap 数据前进行反预乘比较好,或者根据 SDK Level 禁用预乘。

@pandamicro

This comment has been minimized.

Copy link
Contributor

commented Apr 22, 2019

看上去这个损耗确实很高,从 issue 来看,原生层貌似没有好的解决办法,不过不需要用损耗这么高的方式,可以给 HTMLCanvasElement 提供一个手动 premultiply 的方法,然后手动调用。如果不希望改动引擎代码,实在不行就重写 texImage2D 和 texSubImage2D,在这两个函数执行之前检查和处理

@caryliu1999

This comment has been minimized.

Copy link
Contributor Author

commented Apr 23, 2019

将unpremulAlpha的处理放在了texImage2D以及texSubImage2D里面,提交纹理类型为HtmlCanvasElement时直接修改js层存储的数据,不再创建新的array buffer,避免引擎层面updateTexture时多次触发调用。

@caryliu1999

This comment has been minimized.

Copy link
Contributor Author

commented Apr 24, 2019

我觉得这个修复方法对 js 性能太不友好了,原生平台的问题应该尽量在原生平台修复才对,这本来就是底层应该抹平的平台差异。
原生平台返回 BitMap 数据前进行反预乘比较好,或者根据 SDK Level 禁用预乘。

如果希望在原生平台解决,最优的解决就是让不同平台从BitMap取像素数据时不要做预乘处理直接返回实际的RGBA值,win32是代码层面取出像素数据后做了一次预乘(可以直接修改代码取消多余操作),IOS对像素数据的访问不支持非预乘,Android需要判断SDK Level。不同平台差异处理比较大,不是很统一,所以最终没考虑直接在原生层面修改。

@pandamicro pandamicro merged commit 975a826 into cocos-creator-packages:v2.0-release Apr 24, 2019

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.