fix OpenGL image cache behavior for big images; add DrawBuf.invalidate() to update chaches with changed image; fix #222

This commit is contained in:
Vadim Lopatin 2016-03-29 09:36:27 +03:00
parent 1564237c45
commit 59c6df1c06
2 changed files with 34 additions and 10 deletions

View File

@ -98,6 +98,18 @@ class DrawBuf : RefCountedObject {
@property void onDestroyCallback(void function(uint) callback) { _onDestroyCallback = callback; } @property void onDestroyCallback(void function(uint) callback) { _onDestroyCallback = callback; }
@property void function(uint) onDestroyCallback() { return _onDestroyCallback; } @property void function(uint) onDestroyCallback() { return _onDestroyCallback; }
/// Call to remove this image from OpenGL cache when image is updated.
void invalidate() {
static if (ENABLE_OPENGL) {
if (_onDestroyCallback) {
// remove from cache
_onDestroyCallback(_id);
// assign new ID
_id = drawBufIdGenerator++;
}
}
}
// =================================================== // ===================================================
// 9-patch functions (image scaling using 9-patch markup - unscaled frame and scaled middle parts). // 9-patch functions (image scaling using 9-patch markup - unscaled frame and scaled middle parts).
// See Android documentation for details. // See Android documentation for details.

View File

@ -360,28 +360,30 @@ private abstract class GLCache
if (_closed) if (_closed)
return null; return null;
int spacer = (width == _tdx || height == _tdy) ? 0 : 1;
// next line if necessary // next line if necessary
if (_x + width + 2 > _tdx) { if (_x + width + spacer * 2 > _tdx) {
// move to next line // move to next line
_currentLine = _nextLine; _currentLine = _nextLine;
_x = 0; _x = 0;
} }
// check if no room left for glyph height // check if no room left for glyph height
if (_currentLine + height + 2 > _tdy) { if (_currentLine + height + spacer * 2 > _tdy) {
_closed = true; _closed = true;
return null; return null;
} }
cacheItem._rc = Rect(_x + 1, _currentLine + 1, _x + width + 1, _currentLine + height + 1); cacheItem._rc = Rect(_x + spacer, _currentLine + spacer, _x + width + spacer, _currentLine + height + spacer);
if (height && width) { if (height && width) {
if (_nextLine < _currentLine + height + 2) if (_nextLine < _currentLine + height + 2 * spacer)
_nextLine = _currentLine + height + 2; _nextLine = _currentLine + height + 2 * spacer;
if (!_drawbuf) { if (!_drawbuf) {
_drawbuf = new ColorDrawBuf(_tdx, _tdy); _drawbuf = new ColorDrawBuf(_tdx, _tdy);
//_drawbuf.SetBackgroundColor(0x000000); //_drawbuf.SetBackgroundColor(0x000000);
//_drawbuf.SetTextColor(0xFFFFFF); //_drawbuf.SetTextColor(0xFFFFFF);
_drawbuf.fill(0xFF000000); _drawbuf.fill(0xFF000000);
} }
_x += width + 1; _x += width + spacer;
_needUpdateTexture = true; _needUpdateTexture = true;
} }
_itemCount++; _itemCount++;
@ -487,9 +489,17 @@ private class GLImageCache : GLCache
void convertPixelFormat(GLCacheItem item) { void convertPixelFormat(GLCacheItem item) {
Rect rc = item._rc; Rect rc = item._rc;
for (int y = rc.top - 1; y <= rc.bottom; y++) { if (rc.top > 0)
rc.top--;
if (rc.left > 0)
rc.left--;
if (rc.right < _tdx)
rc.right++;
if (rc.bottom < _tdy)
rc.bottom++;
for (int y = rc.top; y < rc.bottom; y++) {
uint * row = _drawbuf.scanLine(y); uint * row = _drawbuf.scanLine(y);
for (int x = rc.left - 1; x <= rc.right; x++) { for (int x = rc.left; x < rc.right; x++) {
uint cl = row[x]; uint cl = row[x];
// invert A // invert A
cl ^= 0xFF000000; cl ^= 0xFF000000;
@ -586,8 +596,10 @@ private class GLImageCache : GLCache
/// draw cached item /// draw cached item
void drawItem(uint objectId, Rect dstrc, Rect srcrc, uint color, int options, Rect * clip, int rotationAngle) { void drawItem(uint objectId, Rect dstrc, Rect srcrc, uint color, int options, Rect * clip, int rotationAngle) {
GLCacheItem* item = objectId in _map; GLCacheItem* item = objectId in _map;
if (item) if (item) {
(cast(GLImageCachePage)item.page).drawItem(*item, dstrc, srcrc, color, options, clip, rotationAngle); auto page = (cast(GLImageCachePage)item.page);
page.drawItem(*item, dstrc, srcrc, color, options, clip, rotationAngle);
}
} }
} }