Skip to content

Commit 325e470

Browse files
committed
Text Renderers/Editors: if they make a texture snapshot, it only happens in render() to avoid multiple texture uploads in the same frame (which should slightly improve performance when text is changing frequently, such as scrolling a list)
1 parent af4c441 commit 325e470

File tree

4 files changed

+130
-95
lines changed

4 files changed

+130
-95
lines changed

source/feathers/controls/text/StageTextTextEditor.as

Lines changed: 34 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -316,6 +316,11 @@ package feathers.controls.text
316316
*/
317317
protected var _needsNewTexture:Boolean = false;
318318

319+
/**
320+
* @private
321+
*/
322+
protected var _needsTextureUpdate:Boolean = false;
323+
319324
/**
320325
* @private
321326
*/
@@ -1225,7 +1230,7 @@ package feathers.controls.text
12251230
{
12261231
painter.excludeFromCache(this);
12271232
}
1228-
if(this.textSnapshot && this._updateSnapshotOnScaleChange)
1233+
if(this.textSnapshot !== null && this._updateSnapshotOnScaleChange)
12291234
{
12301235
var matrix:Matrix = Pool.getMatrix();
12311236
this.getTransformationMatrix(this.stage, matrix);
@@ -1239,10 +1244,32 @@ package feathers.controls.text
12391244
}
12401245
Pool.putMatrix(matrix);
12411246
}
1247+
if(this._needsTextureUpdate)
1248+
{
1249+
this._needsTextureUpdate = false;
1250+
var hasText:Boolean = this._text.length > 0;
1251+
if(hasText)
1252+
{
1253+
this.refreshSnapshot();
1254+
}
1255+
if(this.textSnapshot)
1256+
{
1257+
this.textSnapshot.visible = !this._stageTextHasFocus;
1258+
this.textSnapshot.alpha = hasText ? 1 : 0;
1259+
}
1260+
if(!this._stageTextHasFocus)
1261+
{
1262+
//hide the StageText after the snapshot is created
1263+
//native controls don't necessarily render at the same time
1264+
//as starling, and we don't want to see the text disappear
1265+
//for a moment
1266+
this.stageText.visible = false;
1267+
}
1268+
}
12421269

12431270
//we'll skip this if the text field isn't visible to avoid running
12441271
//that code every frame.
1245-
if(this.stageText && this.stageText.visible)
1272+
if(this.stageText !== null && this.stageText.visible)
12461273
{
12471274
this.refreshViewPortAndFontSize();
12481275
}
@@ -1612,17 +1639,11 @@ package feathers.controls.text
16121639

16131640
if(!this._stageTextHasFocus && (stateInvalid || stylesInvalid || dataInvalid || sizeInvalid || this._needsNewTexture))
16141641
{
1615-
var hasText:Boolean = this._text.length > 0;
1616-
if(hasText)
1617-
{
1618-
this.refreshSnapshot();
1619-
}
1620-
if(this.textSnapshot)
1621-
{
1622-
this.textSnapshot.visible = !this._stageTextHasFocus;
1623-
this.textSnapshot.alpha = hasText ? 1 : 0;
1624-
}
1625-
this.stageText.visible = false;
1642+
//we're going to update the texture in render() because
1643+
//there's a chance that it will be updated more than once per
1644+
//frame if we do it here.
1645+
this._needsTextureUpdate = true;
1646+
this.setRequiresRedraw();
16261647
}
16271648

16281649
this.doPendingActions();

source/feathers/controls/text/TextBlockTextRenderer.as

Lines changed: 20 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -313,7 +313,7 @@ package feathers.controls.text
313313
/**
314314
* @private
315315
*/
316-
protected var _needsUpdateSnapshot:Boolean = false;
316+
protected var _needsTextureUpdate:Boolean = false;
317317

318318
/**
319319
* @private
@@ -1356,32 +1356,32 @@ package feathers.controls.text
13561356
*/
13571357
override public function render(painter:Painter):void
13581358
{
1359-
if(this._needsUpdateSnapshot)
1359+
var starling:Starling = this.stage !== null ? this.stage.starling : Starling.current;
1360+
if(this.textSnapshot !== null && this._updateSnapshotOnScaleChange)
1361+
{
1362+
this.getTransformationMatrix(this.stage, HELPER_MATRIX);
1363+
var globalScaleX:Number = matrixToScaleX(HELPER_MATRIX);
1364+
var globalScaleY:Number = matrixToScaleY(HELPER_MATRIX);
1365+
if(globalScaleX != this._lastGlobalScaleX ||
1366+
globalScaleY != this._lastGlobalScaleY ||
1367+
starling.contentScaleFactor != this._lastGlobalContentScaleFactor)
1368+
{
1369+
//the snapshot needs to be updated because the scale has
1370+
//changed since the last snapshot was taken.
1371+
this.invalidate(INVALIDATION_FLAG_SIZE);
1372+
this.validate();
1373+
}
1374+
}
1375+
if(this._needsTextureUpdate)
13601376
{
1361-
this._needsUpdateSnapshot = false;
1377+
this._needsTextureUpdate = false;
13621378
if(this._content !== null)
13631379
{
13641380
this.refreshSnapshot();
13651381
}
13661382
}
13671383
if(this.textSnapshot !== null)
13681384
{
1369-
var starling:Starling = this.stage !== null ? this.stage.starling : Starling.current;
1370-
if(this._updateSnapshotOnScaleChange)
1371-
{
1372-
this.getTransformationMatrix(this.stage, HELPER_MATRIX);
1373-
var globalScaleX:Number = matrixToScaleX(HELPER_MATRIX);
1374-
var globalScaleY:Number = matrixToScaleY(HELPER_MATRIX);
1375-
if(globalScaleX != this._lastGlobalScaleX ||
1376-
globalScaleY != this._lastGlobalScaleY ||
1377-
starling.contentScaleFactor != this._lastGlobalContentScaleFactor)
1378-
{
1379-
//the snapshot needs to be updated because the scale has
1380-
//changed since the last snapshot was taken.
1381-
this.invalidate(INVALIDATION_FLAG_SIZE);
1382-
this.validate();
1383-
}
1384-
}
13851385
var scaleFactor:Number = starling.contentScaleFactor;
13861386
if(!this._nativeFilters || this._nativeFilters.length === 0)
13871387
{
@@ -1729,7 +1729,7 @@ package feathers.controls.text
17291729
//we're going to update the texture in render() because
17301730
//there's a chance that it will be updated more than once per
17311731
//frame if we do it here.
1732-
this._needsUpdateSnapshot = true;
1732+
this._needsTextureUpdate = true;
17331733
this.setRequiresRedraw();
17341734
}
17351735
}

source/feathers/controls/text/TextFieldTextEditor.as

Lines changed: 34 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -332,6 +332,11 @@ package feathers.controls.text
332332
*/
333333
protected var _lastGlobalScaleY:Number = 0;
334334

335+
/**
336+
* @private
337+
*/
338+
protected var _needsTextureUpdate:Boolean = false;
339+
335340
/**
336341
* @private
337342
*/
@@ -1403,21 +1408,32 @@ package feathers.controls.text
14031408
*/
14041409
override public function render(painter:Painter):void
14051410
{
1406-
if(this.textSnapshot)
1411+
if(this.textSnapshot !== null && this._updateSnapshotOnScaleChange)
14071412
{
1408-
if(this._updateSnapshotOnScaleChange)
1413+
var matrix:Matrix = Pool.getMatrix();
1414+
this.getTransformationMatrix(this.stage, matrix);
1415+
if(matrixToScaleX(matrix) !== this._lastGlobalScaleX ||
1416+
matrixToScaleY(matrix) !== this._lastGlobalScaleY)
14091417
{
1410-
var matrix:Matrix = Pool.getMatrix();
1411-
this.getTransformationMatrix(this.stage, matrix);
1412-
if(matrixToScaleX(matrix) !== this._lastGlobalScaleX ||
1413-
matrixToScaleY(matrix) !== this._lastGlobalScaleY)
1414-
{
1415-
//the snapshot needs to be updated because the scale has
1416-
//changed since the last snapshot was taken.
1417-
this.invalidate(INVALIDATION_FLAG_SIZE);
1418-
this.validate();
1419-
}
1420-
Pool.putMatrix(matrix);
1418+
//the snapshot needs to be updated because the scale has
1419+
//changed since the last snapshot was taken.
1420+
this.invalidate(INVALIDATION_FLAG_SIZE);
1421+
this.validate();
1422+
}
1423+
Pool.putMatrix(matrix);
1424+
}
1425+
if(this._needsTextureUpdate)
1426+
{
1427+
this._needsTextureUpdate = false;
1428+
if(this._useSnapshotDelayWorkaround)
1429+
{
1430+
//sometimes, we need to wait a frame for flash.text.TextField
1431+
//to render properly when drawing to BitmapData.
1432+
this.addEventListener(Event.ENTER_FRAME, refreshSnapshot_enterFrameHandler);
1433+
}
1434+
else
1435+
{
1436+
this.refreshSnapshot();
14211437
}
14221438
this.positionSnapshot();
14231439
}
@@ -2078,16 +2094,11 @@ package feathers.controls.text
20782094

20792095
if(!this._textFieldHasFocus && (sizeInvalid || stylesInvalid || dataInvalid || stateInvalid || this._needsNewTexture))
20802096
{
2081-
if(this._useSnapshotDelayWorkaround)
2082-
{
2083-
//sometimes, we need to wait a frame for flash.text.TextField
2084-
//to render properly when drawing to BitmapData.
2085-
this.addEventListener(Event.ENTER_FRAME, refreshSnapshot_enterFrameHandler);
2086-
}
2087-
else
2088-
{
2089-
this.refreshSnapshot();
2090-
}
2097+
//we're going to update the texture in render() because
2098+
//there's a chance that it will be updated more than once per
2099+
//frame if we do it here.
2100+
this._needsTextureUpdate = true;
2101+
this.setRequiresRedraw();
20912102
}
20922103
this.doPendingActions();
20932104
}

source/feathers/controls/text/TextFieldTextRenderer.as

Lines changed: 42 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -170,6 +170,11 @@ package feathers.controls.text
170170
*/
171171
protected var _snapshotVisibleHeight:int = 0;
172172

173+
/**
174+
* @private
175+
*/
176+
protected var _needsTextureUpdate:Boolean = false;
177+
173178
/**
174179
* @private
175180
*/
@@ -1229,24 +1234,41 @@ package feathers.controls.text
12291234
*/
12301235
override public function render(painter:Painter):void
12311236
{
1232-
if(this.textSnapshot !== null)
1237+
var starling:Starling = this.stage !== null ? this.stage.starling : Starling.current;
1238+
if(this.textSnapshot !== null && this._updateSnapshotOnScaleChange)
12331239
{
1234-
var starling:Starling = this.stage !== null ? this.stage.starling : Starling.current;
1235-
if(this._updateSnapshotOnScaleChange)
1240+
this.getTransformationMatrix(this.stage, HELPER_MATRIX);
1241+
var globalScaleX:Number = matrixToScaleX(HELPER_MATRIX);
1242+
var globalScaleY:Number = matrixToScaleY(HELPER_MATRIX);
1243+
if(globalScaleX != this._lastGlobalScaleX ||
1244+
globalScaleY != this._lastGlobalScaleY ||
1245+
starling.contentScaleFactor != this._lastContentScaleFactor)
12361246
{
1237-
this.getTransformationMatrix(this.stage, HELPER_MATRIX);
1238-
var globalScaleX:Number = matrixToScaleX(HELPER_MATRIX);
1239-
var globalScaleY:Number = matrixToScaleY(HELPER_MATRIX);
1240-
if(globalScaleX != this._lastGlobalScaleX ||
1241-
globalScaleY != this._lastGlobalScaleY ||
1242-
starling.contentScaleFactor != this._lastContentScaleFactor)
1247+
//the snapshot needs to be updated because the scale has
1248+
//changed since the last snapshot was taken.
1249+
this.invalidate(INVALIDATION_FLAG_SIZE);
1250+
this.validate();
1251+
}
1252+
}
1253+
if(this._needsTextureUpdate)
1254+
{
1255+
this._needsTextureUpdate = false;
1256+
if(this._text.length > 0)
1257+
{
1258+
if(this._useSnapshotDelayWorkaround)
12431259
{
1244-
//the snapshot needs to be updated because the scale has
1245-
//changed since the last snapshot was taken.
1246-
this.invalidate(INVALIDATION_FLAG_SIZE);
1247-
this.validate();
1260+
//we need to wait a frame for the TextField to render
1261+
//properly. sometimes two, and this is a known issue.
1262+
this.addEventListener(Event.ENTER_FRAME, enterFrameHandler);
1263+
}
1264+
else
1265+
{
1266+
this.refreshSnapshot();
12481267
}
12491268
}
1269+
}
1270+
if(this.textSnapshot !== null)
1271+
{
12501272
var scaleFactor:Number = starling.contentScaleFactor;
12511273
if(!this._nativeFilters || this._nativeFilters.length === 0)
12521274
{
@@ -1282,11 +1304,13 @@ package feathers.controls.text
12821304
if(snapshotIndex < 0)
12831305
{
12841306
var snapshot:Image = this.textSnapshot;
1307+
snapshot.visible = this._text.length > 0 && this._snapshotWidth > 0 && this._snapshotHeight > 0;
12851308
}
12861309
else
12871310
{
12881311
snapshot = this.textSnapshots[snapshotIndex];
12891312
}
1313+
snapshot.pixelSnapping = this._pixelSnapping;
12901314
snapshot.x = xPosition / scaleFactor;
12911315
snapshot.y = yPosition / scaleFactor;
12921316
snapshotIndex++;
@@ -1629,32 +1653,11 @@ package feathers.controls.text
16291653
{
16301654
this._previousActualWidth = this.actualWidth;
16311655
this._previousActualHeight = this.actualHeight;
1632-
var hasText:Boolean = this._text.length > 0;
1633-
if(hasText)
1634-
{
1635-
if(this._useSnapshotDelayWorkaround)
1636-
{
1637-
//we need to wait a frame for the TextField to render
1638-
//properly. sometimes two, and this is a known issue.
1639-
this.addEventListener(Event.ENTER_FRAME, enterFrameHandler);
1640-
}
1641-
else
1642-
{
1643-
this.refreshSnapshot();
1644-
}
1645-
}
1646-
if(this.textSnapshot)
1647-
{
1648-
this.textSnapshot.visible = hasText && this._snapshotWidth > 0 && this._snapshotHeight > 0;
1649-
this.textSnapshot.pixelSnapping = this._pixelSnapping;
1650-
}
1651-
if(this.textSnapshots)
1652-
{
1653-
for each(var snapshot:Image in this.textSnapshots)
1654-
{
1655-
snapshot.pixelSnapping = this._pixelSnapping;
1656-
}
1657-
}
1656+
//we're going to update the texture in render() because
1657+
//there's a chance that it will be updated more than once per
1658+
//frame if we do it here.
1659+
this._needsTextureUpdate = true;
1660+
this.setRequiresRedraw();
16581661
}
16591662
}
16601663

0 commit comments

Comments
 (0)