Skip to content

Commit 90ed303

Browse files
committed
modify webgl renderer
1 parent b53e4f8 commit 90ed303

File tree

4 files changed

+239
-159
lines changed

4 files changed

+239
-159
lines changed

build/egret/egret.web.js

Lines changed: 101 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -5325,12 +5325,13 @@ var egret;
53255325
this.contextLost = false;
53265326
this.currentBaseTexture = null;
53275327
this.currentBatchSize = 0;
5328+
this.drawData = [];
53285329
this.$drawCalls = 0;
53295330
this.$computeDrawCall = false;
53305331
this.globalMatrix = new egret.Matrix();
53315332
this.savedGlobalMatrix = new egret.Matrix();
53325333
this._globalAlpha = 1;
5333-
this.stencilList = [];
5334+
this.$stencilList = [];
53345335
this.graphicsPoints = null;
53355336
this.graphicsIndices = null;
53365337
this.graphicsBuffer = null;
@@ -5453,7 +5454,7 @@ var egret;
54535454
* 获取指定坐标的像素
54545455
*/
54555456
p.getPixel = function (x, y) {
5456-
return null; //this.context.getImageData(x, y, 1, 1).data;
5457+
return []; //this.context.getImageData(x, y, 1, 1).data;
54575458
};
54585459
/**
54595460
* 转换成base64字符串,如果图片(或者包含的图片)跨域,则返回null
@@ -5570,8 +5571,9 @@ var egret;
55705571
this.createWebGLTexture(texture);
55715572
var webGLTexture = texture["webGLTexture"][this.glID];
55725573
if (webGLTexture !== this.currentBaseTexture || this.currentBatchSize >= this.size - 1) {
5573-
this.$drawWebGL();
5574+
//this.$drawWebGL();
55745575
this.currentBaseTexture = webGLTexture;
5576+
this.drawData.push({ texture: this.currentBaseTexture, count: 0 });
55755577
}
55765578
//计算出绘制矩阵,之后把矩阵还原回之前的
55775579
var locWorldTransform = this.globalMatrix;
@@ -5643,21 +5645,39 @@ var egret;
56435645
// alpha
56445646
vertices[index++] = alpha;
56455647
this.currentBatchSize++;
5648+
this.drawData[this.drawData.length - 1].count++;
56465649
};
56475650
p.$drawWebGL = function () {
56485651
if (this.currentBatchSize == 0 || this.contextLost) {
56495652
return;
56505653
}
5651-
if (this.$computeDrawCall) {
5652-
this.$drawCalls++;
5653-
}
56545654
this.start();
56555655
var gl = this.context;
5656-
gl.bindTexture(gl.TEXTURE_2D, this.currentBaseTexture);
56575656
var view = this.vertices.subarray(0, this.currentBatchSize * 4 * this.vertSize);
56585657
gl.bufferSubData(gl.ARRAY_BUFFER, 0, view);
5659-
gl.drawElements(gl.TRIANGLES, this.currentBatchSize * 6, gl.UNSIGNED_SHORT, 0);
5658+
var length = this.drawData.length;
5659+
var offset = 0;
5660+
for (var i = 0; i < length; i++) {
5661+
var data = this.drawData[i];
5662+
if (data.texture) {
5663+
gl.bindTexture(gl.TEXTURE_2D, data.texture);
5664+
var size = data.count * 6;
5665+
gl.drawElements(gl.TRIANGLES, size, gl.UNSIGNED_SHORT, offset * 2);
5666+
offset += size;
5667+
if (this.$computeDrawCall) {
5668+
this.$drawCalls++;
5669+
}
5670+
}
5671+
else {
5672+
var blendModeWebGL = WebGLRenderBuffer.blendModesForGL[data];
5673+
if (blendModeWebGL) {
5674+
this.context.blendFunc(blendModeWebGL[0], blendModeWebGL[1]);
5675+
}
5676+
}
5677+
}
5678+
this.drawData.length = 0;
56605679
this.currentBatchSize = 0;
5680+
this.currentBaseTexture = null;
56615681
};
56625682
p.start = function () {
56635683
if (this.contextLost) {
@@ -5724,24 +5744,21 @@ var egret;
57245744
};
57255745
p.setGlobalCompositeOperation = function (value) {
57265746
if (this.currentBlendMode != value) {
5727-
var blendModeWebGL = WebGLRenderBuffer.blendModesForGL[value];
5728-
if (blendModeWebGL) {
5729-
this.$drawWebGL();
5730-
this.context.blendFunc(blendModeWebGL[0], blendModeWebGL[1]);
5731-
this.currentBlendMode = value;
5732-
}
5747+
this.drawData.push(value);
5748+
this.currentBlendMode = value;
5749+
this.currentBaseTexture = null;
57335750
}
57345751
};
57355752
p.pushMask = function (mask) {
57365753
//todo 把绘制数据缓存提升性能
57375754
this.$drawWebGL();
57385755
var gl = this.context;
5739-
if (this.stencilList.length === 0) {
5756+
if (this.$stencilList.length === 0) {
57405757
gl.enable(gl.STENCIL_TEST);
57415758
gl.clear(gl.STENCIL_BUFFER_BIT);
57425759
}
5743-
var level = this.stencilList.length;
5744-
this.stencilList.push(mask);
5760+
var level = this.$stencilList.length;
5761+
this.$stencilList.push(mask);
57455762
gl.colorMask(false, false, false, false);
57465763
gl.stencilFunc(gl.EQUAL, level, 0xFF);
57475764
gl.stencilOp(gl.KEEP, gl.KEEP, gl.INCR);
@@ -5762,12 +5779,12 @@ var egret;
57625779
p.popMask = function () {
57635780
this.$drawWebGL();
57645781
var gl = this.context;
5765-
var mask = this.stencilList.pop();
5766-
if (this.stencilList.length === 0) {
5782+
var mask = this.$stencilList.pop();
5783+
if (this.$stencilList.length === 0) {
57675784
gl.disable(gl.STENCIL_TEST);
57685785
}
57695786
else {
5770-
var level = this.stencilList.length;
5787+
var level = this.$stencilList.length;
57715788
gl.colorMask(false, false, false, false);
57725789
gl.stencilFunc(gl.EQUAL, level + 1, 0xFF);
57735790
gl.stencilOp(gl.KEEP, gl.KEEP, gl.DECR);
@@ -6033,6 +6050,7 @@ var egret;
60336050
}
60346051
else {
60356052
if (child["isFPS"]) {
6053+
buffer.$drawWebGL();
60366054
buffer.$computeDrawCall = false;
60376055
this.drawDisplayObject(child, buffer, dirtyList, matrix, child.$displayList, clipRegion, root);
60386056
buffer.$drawWebGL();
@@ -6050,7 +6068,6 @@ var egret;
60506068
* @private
60516069
*/
60526070
p.drawWithClip = function (displayObject, buffer, dirtyList, matrix, clipRegion, root) {
6053-
//todo 可以使用stencil代替混合模式
60546071
var drawCalls = 0;
60556072
var hasBlendMode = (displayObject.$blendMode !== 0);
60566073
if (hasBlendMode) {
@@ -6128,33 +6145,55 @@ var egret;
61286145
egret.Matrix.release(displayMatrix);
61296146
return drawCalls;
61306147
}
6131-
//绘制显示对象自身,若有scrollRect,应用clip
6132-
var displayBuffer = this.createRenderBuffer(region.width, region.height);
6133-
var displayContext = displayBuffer.context;
6134-
if (!displayContext) {
6135-
drawCalls += this.drawDisplayObject(displayObject, buffer, dirtyList, matrix, displayObject.$displayList, clipRegion, root);
6148+
//没有遮罩,同时显示对象没有子项
6149+
if (!mask && (!displayObject.$children || displayObject.$children.length == 0)) {
6150+
if (scrollRect) {
6151+
buffer.pushMask(scrollRect);
6152+
}
6153+
var offsetM = egret.Matrix.create().setTo(1, 0, 0, 1, 0, 0);
6154+
//绘制显示对象
6155+
if (hasBlendMode) {
6156+
buffer.setGlobalCompositeOperation(compositeOp);
6157+
}
6158+
drawCalls += this.drawDisplayObject(displayObject, buffer, dirtyList, offsetM, displayObject.$displayList, region, null);
6159+
egret.Matrix.release(offsetM);
6160+
if (hasBlendMode) {
6161+
buffer.setGlobalCompositeOperation(defaultCompositeOp);
6162+
}
61366163
egret.sys.Region.release(region);
61376164
egret.Matrix.release(displayMatrix);
61386165
return drawCalls;
61396166
}
6140-
if (scrollRect) {
6141-
var m = displayMatrix;
6142-
displayBuffer.setTransform(m.a, m.b, m.c, m.d, m.tx - region.minX, m.ty - region.minY);
6143-
displayBuffer.pushMask(scrollRect);
6144-
}
6145-
displayBuffer.setTransform(1, 0, 0, 1, -region.minX, -region.minY);
6146-
var offsetM = egret.Matrix.create().setTo(1, 0, 0, 1, -region.minX, -region.minY);
6147-
drawCalls += this.drawDisplayObject(displayObject, displayBuffer, dirtyList, offsetM, displayObject.$displayList, region, root ? displayObject : null);
6148-
egret.Matrix.release(offsetM);
6149-
//绘制遮罩
6150-
if (mask) {
6151-
//如果只有一次绘制或是已经被cache直接绘制到displayContext
6152-
var maskRenderNode = mask.$getRenderNode();
6153-
if (maskRenderNode && maskRenderNode.$getRenderCount() == 1 || mask.$displayList) {
6154-
displayBuffer.setGlobalCompositeOperation("destination-in");
6155-
drawCalls += this.drawDisplayObject(mask, displayBuffer, dirtyList, offsetM, mask.$displayList, region, root ? mask : null);
6167+
else {
6168+
//绘制显示对象自身,若有scrollRect,应用clip
6169+
var displayBuffer = this.createRenderBuffer(region.width, region.height);
6170+
var displayContext = displayBuffer.context;
6171+
if (!displayContext) {
6172+
drawCalls += this.drawDisplayObject(displayObject, buffer, dirtyList, matrix, displayObject.$displayList, clipRegion, root);
6173+
egret.sys.Region.release(region);
6174+
egret.Matrix.release(displayMatrix);
6175+
return drawCalls;
61566176
}
6157-
else {
6177+
if (scrollRect) {
6178+
var m = displayMatrix;
6179+
displayBuffer.setTransform(m.a, m.b, m.c, m.d, m.tx - region.minX, m.ty - region.minY);
6180+
displayBuffer.pushMask(scrollRect);
6181+
}
6182+
displayBuffer.setTransform(1, 0, 0, 1, -region.minX, -region.minY);
6183+
var offsetM = egret.Matrix.create().setTo(1, 0, 0, 1, -region.minX, -region.minY);
6184+
drawCalls += this.drawDisplayObject(displayObject, displayBuffer, dirtyList, offsetM, displayObject.$displayList, region, root ? displayObject : null);
6185+
egret.Matrix.release(offsetM);
6186+
//绘制遮罩
6187+
if (mask) {
6188+
//如果只有一次绘制或是已经被cache直接绘制到displayContext
6189+
//webgl暂时无法添加,因为会有边界像素没有被擦除
6190+
//var maskRenderNode = mask.$getRenderNode();
6191+
//if (maskRenderNode && maskRenderNode.$getRenderCount() == 1 || mask.$displayList) {
6192+
// displayBuffer.setGlobalCompositeOperation("destination-in");
6193+
// drawCalls += this.drawDisplayObject(mask, displayBuffer, dirtyList, offsetM,
6194+
// mask.$displayList, region, root ? mask : null);
6195+
//}
6196+
//else {
61586197
var maskBuffer = this.createRenderBuffer(region.width, region.height);
61596198
var maskContext = maskBuffer.context;
61606199
if (!maskContext) {
@@ -6180,26 +6219,27 @@ var egret;
61806219
}
61816220
renderBufferPool.push(maskBuffer);
61826221
}
6183-
}
6184-
//绘制结果到屏幕
6185-
if (drawCalls > 0) {
6186-
drawCalls++;
6187-
if (hasBlendMode) {
6188-
buffer.setGlobalCompositeOperation(compositeOp);
6189-
}
6190-
buffer.setGlobalAlpha(1);
6191-
buffer.setTransform(1, 0, 0, 1, region.minX + matrix.tx, region.minY + matrix.ty);
6192-
displayBuffer.$drawWebGL();
6193-
web.WebGLUtils.deleteWebGLTexture(displayBuffer.surface);
6194-
buffer.drawImage(displayBuffer.surface, 0, 0, displayBuffer.surface.width, displayBuffer.surface.height, 0, 0, displayBuffer.surface.width, displayBuffer.surface.height);
6195-
if (hasBlendMode) {
6196-
buffer.setGlobalCompositeOperation(defaultCompositeOp);
6222+
//绘制结果到屏幕
6223+
if (drawCalls > 0) {
6224+
drawCalls++;
6225+
if (hasBlendMode) {
6226+
buffer.setGlobalCompositeOperation(compositeOp);
6227+
}
6228+
buffer.setGlobalAlpha(1);
6229+
buffer.setTransform(1, 0, 0, 1, region.minX + matrix.tx, region.minY + matrix.ty);
6230+
displayBuffer.$drawWebGL();
6231+
web.WebGLUtils.deleteWebGLTexture(displayBuffer.surface);
6232+
buffer.drawImage(displayBuffer.surface, 0, 0, displayBuffer.surface.width, displayBuffer.surface.height, 0, 0, displayBuffer.surface.width, displayBuffer.surface.height);
6233+
if (hasBlendMode) {
6234+
buffer.setGlobalCompositeOperation(defaultCompositeOp);
6235+
}
61976236
}
6237+
displayBuffer.setGlobalCompositeOperation(defaultCompositeOp);
6238+
renderBufferPool.push(displayBuffer);
6239+
egret.sys.Region.release(region);
6240+
egret.Matrix.release(displayMatrix);
6241+
return drawCalls;
61986242
}
6199-
renderBufferPool.push(displayBuffer);
6200-
egret.sys.Region.release(region);
6201-
egret.Matrix.release(displayMatrix);
6202-
return drawCalls;
62036243
};
62046244
/**
62056245
* @private
@@ -6351,7 +6391,6 @@ var egret;
63516391
}
63526392
buffer.transform(1, 0, 0, 1, -node.x, -node.y);
63536393
}
6354-
buffer.$drawWebGL();
63556394
node.dirtyRender = false;
63566395
};
63576396
/**
@@ -6390,7 +6429,6 @@ var egret;
63906429
}
63916430
buffer.transform(1, 0, 0, 1, -node.x, -node.y);
63926431
}
6393-
buffer.$drawWebGL();
63946432
node.dirtyRender = false;
63956433
};
63966434
p.renderGroup = function (groupNode, buffer) {

build/egret/egret.web.min.js

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/egret/web/rendering/webgl/WebGLRenderBuffer.ts

Lines changed: 38 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -335,8 +335,9 @@ module egret.web {
335335
this.createWebGLTexture(texture);
336336
var webGLTexture = texture["webGLTexture"][this.glID];
337337
if (webGLTexture !== this.currentBaseTexture || this.currentBatchSize >= this.size - 1) {
338-
this.$drawWebGL();
338+
//this.$drawWebGL();
339339
this.currentBaseTexture = webGLTexture;
340+
this.drawData.push({texture: this.currentBaseTexture, count: 0});
340341
}
341342

342343
//计算出绘制矩阵,之后把矩阵还原回之前的
@@ -419,25 +420,46 @@ module egret.web {
419420
vertices[index++] = alpha;
420421

421422
this.currentBatchSize++;
423+
this.drawData[this.drawData.length - 1].count++;
422424
}
423425

426+
private drawData = [];
424427
public $drawCalls:number = 0;
425428
public $computeDrawCall:boolean = false;
426429

427430
public $drawWebGL():void {
428431
if (this.currentBatchSize == 0 || this.contextLost) {
429432
return;
430433
}
431-
if(this.$computeDrawCall) {
432-
this.$drawCalls++;
433-
}
434434
this.start();
435435
var gl:any = this.context;
436-
gl.bindTexture(gl.TEXTURE_2D, this.currentBaseTexture);
436+
437437
var view = this.vertices.subarray(0, this.currentBatchSize * 4 * this.vertSize);
438438
gl.bufferSubData(gl.ARRAY_BUFFER, 0, view);
439-
gl.drawElements(gl.TRIANGLES, this.currentBatchSize * 6, gl.UNSIGNED_SHORT, 0);
439+
440+
var length = this.drawData.length;
441+
var offset = 0;
442+
for (var i = 0; i < length; i++) {
443+
var data = this.drawData[i];
444+
if (data.texture) {
445+
gl.bindTexture(gl.TEXTURE_2D, data.texture);
446+
var size = data.count * 6;
447+
gl.drawElements(gl.TRIANGLES, size, gl.UNSIGNED_SHORT, offset * 2);
448+
offset += size;
449+
if (this.$computeDrawCall) {
450+
this.$drawCalls++;
451+
}
452+
}
453+
else {
454+
var blendModeWebGL = WebGLRenderBuffer.blendModesForGL[data];
455+
if (blendModeWebGL) {
456+
this.context.blendFunc(blendModeWebGL[0], blendModeWebGL[1]);
457+
}
458+
}
459+
}
460+
this.drawData.length = 0;
440461
this.currentBatchSize = 0;
462+
this.currentBaseTexture = null;
441463
}
442464

443465
private vertexBuffer;
@@ -531,28 +553,25 @@ module egret.web {
531553

532554
public setGlobalCompositeOperation(value:string) {
533555
if (this.currentBlendMode != value) {
534-
var blendModeWebGL = WebGLRenderBuffer.blendModesForGL[value];
535-
if (blendModeWebGL) {
536-
this.$drawWebGL();
537-
this.context.blendFunc(blendModeWebGL[0], blendModeWebGL[1]);
538-
this.currentBlendMode = value;
539-
}
556+
this.drawData.push(value);
557+
this.currentBlendMode = value;
558+
this.currentBaseTexture = null;
540559
}
541560
}
542561

543-
private stencilList = [];
562+
public $stencilList = [];
544563

545564
public pushMask(mask):void {
546565
//todo 把绘制数据缓存提升性能
547566
this.$drawWebGL();
548567
var gl = this.context;
549-
if (this.stencilList.length === 0) {
568+
if (this.$stencilList.length === 0) {
550569
gl.enable(gl.STENCIL_TEST);
551570
gl.clear(gl.STENCIL_BUFFER_BIT);
552571
}
553-
var level = this.stencilList.length;
572+
var level = this.$stencilList.length;
554573

555-
this.stencilList.push(mask);
574+
this.$stencilList.push(mask);
556575

557576
gl.colorMask(false, false, false, false);
558577
gl.stencilFunc(gl.EQUAL, level, 0xFF);
@@ -576,13 +595,13 @@ module egret.web {
576595
this.$drawWebGL();
577596
var gl = this.context;
578597

579-
var mask = this.stencilList.pop();
598+
var mask = this.$stencilList.pop();
580599

581-
if (this.stencilList.length === 0) {
600+
if (this.$stencilList.length === 0) {
582601
gl.disable(gl.STENCIL_TEST);
583602
}
584603
else {
585-
var level = this.stencilList.length;
604+
var level = this.$stencilList.length;
586605
gl.colorMask(false, false, false, false);
587606
gl.stencilFunc(gl.EQUAL, level + 1, 0xFF);
588607
gl.stencilOp(gl.KEEP, gl.KEEP, gl.DECR);

0 commit comments

Comments
 (0)