Browse Source

Merge pull request #1323 from nockawa/master

Canvas2d: refresh reissued when failing + Sprite2d doesn't dispose its Texture on dispose
Loïc Baumann 9 years ago
parent
commit
947da2d474

+ 7 - 0
src/Canvas2d/babylon.canvas2d.ts

@@ -459,6 +459,7 @@
                 pii.canvasPointerPos.x = localPosition.x;
                 pii.canvasPointerPos.y = localPosition.y;
             }
+            //console.log(`UpdatePointerInfo for ${this.id}, X:${pii.canvasPointerPos.x}, Y:${pii.canvasPointerPos.y}`);
             pii.mouseWheelDelta = 0;
 
             if (eventData.type === PointerEventTypes.POINTERWHEEL) {
@@ -1253,6 +1254,12 @@
             this._updateTrackedNodes();
 
             this._updateCanvasState(false);
+
+            // Nothing to do is the Canvas is not visible
+            if (this.isVisible === false) {
+                return;
+            }
+
             if (!this._isScreenSpace) {
                 this._updateAdaptiveSizeWorldCanvas();
             }

+ 19 - 7
src/Canvas2d/babylon.group2d.ts

@@ -335,8 +335,9 @@
             let sortedDirtyList: Prim2DBase[] = null;
 
             // Update the Global Transformation and visibility status of the changed primitives
-            if ((this._renderableData._primDirtyList.length > 0) || context.forceRefreshPrimitive) {
-                sortedDirtyList = this._renderableData._primDirtyList.sort((a, b) => a.hierarchyDepth - b.hierarchyDepth);
+            let rd = this._renderableData;
+            if ((rd._primDirtyList.length > 0) || context.forceRefreshPrimitive) {
+                sortedDirtyList = rd._primDirtyList.sort((a, b) => a.hierarchyDepth - b.hierarchyDepth);
                 this.updateCachedStatesOf(sortedDirtyList, true);
             }
 
@@ -378,10 +379,12 @@
                 this._viewportSize = newSize;
             }
 
-            if ((this._renderableData._primDirtyList.length > 0) || context.forceRefreshPrimitive) {
+            if ((rd._primDirtyList.length > 0) || context.forceRefreshPrimitive) {
                 // If the group is cached, set the dirty flag to true because of the incoming changes
                 this._cacheGroupDirty = this._isCachedGroup;
 
+                rd._primNewDirtyList.splice(0);
+
                 // If it's a force refresh, prepare all the children
                 if (context.forceRefreshPrimitive) {
                     for (let p of this._children) {
@@ -391,7 +394,7 @@
                     // Each primitive that changed at least once was added into the primDirtyList, we have to sort this level using
                     //  the hierarchyDepth in order to prepare primitives from top to bottom
                     if (!sortedDirtyList) {
-                        sortedDirtyList = this._renderableData._primDirtyList.sort((a, b) => a.hierarchyDepth - b.hierarchyDepth);
+                        sortedDirtyList = rd._primDirtyList.sort((a, b) => a.hierarchyDepth - b.hierarchyDepth);
                     }
 
                     sortedDirtyList.forEach(p => {
@@ -405,12 +408,19 @@
                 }
 
                 // Everything is updated, clear the dirty list
-                this._renderableData._primDirtyList.forEach(p => p._resetPropertiesDirty());
-                this._renderableData._primDirtyList.splice(0);
+                rd._primDirtyList.forEach(p => {
+                    if (rd._primNewDirtyList.indexOf(p) === -1) {
+                        p._resetPropertiesDirty();
+                    } else {
+                        p._setFlags(SmartPropertyPrim.flagNeedRefresh);
+                    }
+                });
+                rd._primDirtyList.splice(0);
+                rd._primDirtyList = rd._primDirtyList.concat(rd._primNewDirtyList);
             }
 
             // A renderable group has a list of direct children that are also renderable groups, we recurse on them to also prepare them
-            this._renderableData._childrenRenderableGroups.forEach(g => {
+            rd._childrenRenderableGroups.forEach(g => {
                 g._prepareGroupRender(context);
             });
         }
@@ -953,6 +963,7 @@
     export class RenderableGroupData {
         constructor() {
             this._primDirtyList = new Array<Prim2DBase>();
+            this._primNewDirtyList = new Array<Prim2DBase>();
             this._childrenRenderableGroups = new Array<Group2D>();
             this._renderGroupInstancesInfo = new StringDictionary<GroupInstanceInfo>();
             this._transparentPrimitives = new Array<TransparentPrimitiveInfo>();
@@ -1033,6 +1044,7 @@
         }
 
         _primDirtyList: Array<Prim2DBase>;
+        _primNewDirtyList: Array<Prim2DBase>;
         _childrenRenderableGroups: Array<Group2D>;
         _renderGroupInstancesInfo: StringDictionary<GroupInstanceInfo>;
 

+ 1 - 1
src/Canvas2d/babylon.prim2dBase.ts

@@ -2591,7 +2591,7 @@
         }
 
         public _needPrepare(): boolean {
-            return this._areSomeFlagsSet(SmartPropertyPrim.flagVisibilityChanged | SmartPropertyPrim.flagModelDirty) || (this._instanceDirtyFlags !== 0) || (this._globalTransformProcessStep !== this._globalTransformStep);
+            return this._areSomeFlagsSet(SmartPropertyPrim.flagVisibilityChanged | SmartPropertyPrim.flagModelDirty | SmartPropertyPrim.flagNeedRefresh) || (this._instanceDirtyFlags !== 0) || (this._globalTransformProcessStep !== this._globalTransformStep);
         }
 
         public _prepareRender(context: PrepareRender2DContext) {

+ 6 - 1
src/Canvas2d/babylon.renderablePrim2d.ts

@@ -480,7 +480,7 @@
             // At this stage we have everything correctly initialized, ModelRenderCache is setup, Model Instance data are good too, they have allocated elements in the Instanced DynamicFloatArray.
 
             // The last thing to do is check if the instanced related data must be updated because a InstanceLevel property had changed or the primitive visibility changed.
-            if (this._isFlagSet(SmartPropertyPrim.flagVisibilityChanged) || context.forceRefreshPrimitive || newInstance || (this._instanceDirtyFlags !== 0) || (this._globalTransformProcessStep !== this._globalTransformStep) || this._mustUpdateInstance()) {
+            if (this._areSomeFlagsSet(SmartPropertyPrim.flagVisibilityChanged | SmartPropertyPrim.flagNeedRefresh) || context.forceRefreshPrimitive || newInstance || (this._instanceDirtyFlags !== 0) || (this._globalTransformProcessStep !== this._globalTransformStep) || this._mustUpdateInstance()) {
 
                 this._updateInstanceDataParts(gii);
             }
@@ -718,6 +718,11 @@
                     if (part.dataElements) {
                         part.freeElements();
                     }
+
+                    // The refresh couldn't succeed, push the primitive to be dirty again for the next render
+                    if (this.isVisible) {
+                        rd._primNewDirtyList.push(this);
+                    }
                 }
 
                 rebuildTrans = rebuildTrans || part.arrayLengthChanged || justAllocated;

+ 2 - 1
src/Canvas2d/babylon.smartPropertyPrim.ts

@@ -442,7 +442,7 @@
 
         public _resetPropertiesDirty() {
             this._instanceDirtyFlags = 0;
-            this._clearFlags(SmartPropertyPrim.flagPrimInDirtyList);
+            this._clearFlags(SmartPropertyPrim.flagPrimInDirtyList | SmartPropertyPrim.flagNeedRefresh);
         }
 
         /**
@@ -632,6 +632,7 @@
         public static flagActualOpacityDirty     = 0x0004000;    // set if the actualOpactity should be recomputed
         public static flagPrimInDirtyList        = 0x0008000;    // set if the primitive is in the primDirtyList
         public static flagIsContainer            = 0x0010000;    // set if the primitive is a container
+        public static flagNeedRefresh            = 0x0020000;    // set if the primitive wasn't successful at refresh
 
         private   _flags             : number;
         private   _externalData      : StringDictionary<Object>;

+ 4 - 4
src/Canvas2d/babylon.sprite2d.ts

@@ -73,10 +73,10 @@
                 this.ib = null;
             }
 
-            if (this.texture) {
-                this.texture.dispose();
-                this.texture = null;
-            }
+            //if (this.texture) {
+            //    this.texture.dispose();
+            //    this.texture = null;
+            //}
 
             this.effect = null;
             this.effectInstanced = null;