1a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas Roard/* 2a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas Roard * Copyright 2010, The Android Open Source Project 3a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas Roard * 4a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas Roard * Redistribution and use in source and binary forms, with or without 5a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas Roard * modification, are permitted provided that the following conditions 6a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas Roard * are met: 7a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas Roard * * Redistributions of source code must retain the above copyright 8a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas Roard * notice, this list of conditions and the following disclaimer. 9a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas Roard * * Redistributions in binary form must reproduce the above copyright 10a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas Roard * notice, this list of conditions and the following disclaimer in the 11a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas Roard * documentation and/or other materials provided with the distribution. 12a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas Roard * 13a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas Roard * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY 14a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas Roard * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 15a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas Roard * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 16a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas Roard * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR 17a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas Roard * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 18a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas Roard * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 19a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas Roard * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 20a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas Roard * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 21a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas Roard * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 22a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas Roard * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 23a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas Roard * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 24a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas Roard */ 25a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas Roard 26d487c56b47c747d3e331ee1892e4c0473363afd2Chris Craik#define LOG_TAG "TilesManager" 27d487c56b47c747d3e331ee1892e4c0473363afd2Chris Craik#define LOG_NDEBUG 1 28d487c56b47c747d3e331ee1892e4c0473363afd2Chris Craik 29a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas Roard#include "config.h" 30a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas Roard#include "TilesManager.h" 31a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas Roard 32a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas Roard#if USE(ACCELERATED_COMPOSITING) 33a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas Roard 34d487c56b47c747d3e331ee1892e4c0473363afd2Chris Craik#include "AndroidLog.h" 35594c6b805969c2673c84d1d1d1a3556ce376ac7aChris Craik#include "GLWebViewState.h" 36a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas Roard#include "SkCanvas.h" 37211482b53e73a386e2aabb0d3acb92e0e7ea22d4Nicolas Roard#include "SkDevice.h" 38a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas Roard#include "SkPaint.h" 39594c6b805969c2673c84d1d1d1a3556ce376ac7aChris Craik#include "Tile.h" 40594c6b805969c2673c84d1d1d1a3556ce376ac7aChris Craik#include "TileTexture.h" 41594c6b805969c2673c84d1d1d1a3556ce376ac7aChris Craik#include "TransferQueue.h" 42594c6b805969c2673c84d1d1d1a3556ce376ac7aChris Craik 437c554a61cb935660cdc86905d040c781b490150fTeng-Hui Zhu#include <android/native_window.h> 44f56ebc1167a793612f34175b5e33db5cef631457Derek Sollenberger#include <cutils/atomic.h> 45ddbf1e63de50066df17c19a621d17634acde2dfaAndy McFadden#include <gui/GLConsumer.h> 464533237f156ff61f2486d0e6d748eafa8ce4d3d3Mathias Agopian#include <gui/Surface.h> 47a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas Roard#include <wtf/CurrentTime.h> 48a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas Roard 494a59c354560ed255d45ad00dbdbed13f045c557eChris Craik// Important: We need at least twice as many textures as is needed to cover 504a59c354560ed255d45ad00dbdbed13f045c557eChris Craik// one viewport, otherwise the allocation may stall. 514a59c354560ed255d45ad00dbdbed13f045c557eChris Craik// We need n textures for one TiledPage, and another n textures for the 524a59c354560ed255d45ad00dbdbed13f045c557eChris Craik// second page used when scaling. 53ce0e4b6b423e45f5a1c2eeedd8a5eff9d24f666eTeng-Hui Zhu// In our case, we use 256*256 textures. Both base and layers can use up to 54ce0e4b6b423e45f5a1c2eeedd8a5eff9d24f666eTeng-Hui Zhu// MAX_TEXTURE_ALLOCATION textures, which is 224MB GPU memory in total. 55ce0e4b6b423e45f5a1c2eeedd8a5eff9d24f666eTeng-Hui Zhu// For low end graphics systems, we cut this upper limit to half. 56ce0e4b6b423e45f5a1c2eeedd8a5eff9d24f666eTeng-Hui Zhu// We've found the viewport dependent value m_currentTextureCount is a reasonable 57ebcd36bcdbefb452a0be4e9e452a054ffdff4763Teng-Hui Zhu// number to cap the layer tile texturs, it worked on both phones and tablets. 58ebcd36bcdbefb452a0be4e9e452a054ffdff4763Teng-Hui Zhu// TODO: after merge the pool of base tiles and layer tiles, we should revisit 59ebcd36bcdbefb452a0be4e9e452a054ffdff4763Teng-Hui Zhu// the logic of allocation management. 605ab250a6ffd49127ffe53059518204cfe5eea6f0Chris Craik#define MAX_TEXTURE_ALLOCATION ((10+TILE_PREFETCH_DISTANCE*2)*(7+TILE_PREFETCH_DISTANCE*2)*4) 615a18cae6b44f84a00cfdda598023a158a7310763Teng-Hui Zhu#define TILE_WIDTH 256 625a18cae6b44f84a00cfdda598023a158a7310763Teng-Hui Zhu#define TILE_HEIGHT 256 63a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas Roard 64211482b53e73a386e2aabb0d3acb92e0e7ea22d4Nicolas Roard#define BYTES_PER_PIXEL 4 // 8888 config 65211482b53e73a386e2aabb0d3acb92e0e7ea22d4Nicolas Roard 66c4718e6733cb345bafc3a95a9e1c234047bfde7eNicolas Roard#define LAYER_TEXTURES_DESTROY_TIMEOUT 60 // If we do not need layers for 60 seconds, free the textures 67c4718e6733cb345bafc3a95a9e1c234047bfde7eNicolas Roard 68334c36c686871998bf6c4ac958dfe3b3d5a87033Chris Craik// Eventually this should be dynamically be determined, and smart scheduling 69334c36c686871998bf6c4ac958dfe3b3d5a87033Chris Craik// between the generators should be implemented 70334c36c686871998bf6c4ac958dfe3b3d5a87033Chris Craik#define NUM_TEXTURES_GENERATORS 1 71334c36c686871998bf6c4ac958dfe3b3d5a87033Chris Craik 72a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas Roardnamespace WebCore { 73a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas Roard 74522c8aecb5c6a797ceb59e8eaa9ab44e3a5fda54Shimeng (Simon) Wangint TilesManager::getMaxTextureAllocation() 75522c8aecb5c6a797ceb59e8eaa9ab44e3a5fda54Shimeng (Simon) Wang{ 76ce0e4b6b423e45f5a1c2eeedd8a5eff9d24f666eTeng-Hui Zhu if (m_maxTextureAllocation == -1) { 77ce0e4b6b423e45f5a1c2eeedd8a5eff9d24f666eTeng-Hui Zhu GLint glMaxTextureSize = 0; 78ce0e4b6b423e45f5a1c2eeedd8a5eff9d24f666eTeng-Hui Zhu glGetIntegerv(GL_MAX_TEXTURE_SIZE, &glMaxTextureSize); 79ce0e4b6b423e45f5a1c2eeedd8a5eff9d24f666eTeng-Hui Zhu GLUtils::checkGlError("TilesManager::getMaxTextureAllocation"); 80ce0e4b6b423e45f5a1c2eeedd8a5eff9d24f666eTeng-Hui Zhu // Half of glMaxTextureSize can be used for base, the other half for layers. 81ce0e4b6b423e45f5a1c2eeedd8a5eff9d24f666eTeng-Hui Zhu m_maxTextureAllocation = std::min(MAX_TEXTURE_ALLOCATION, glMaxTextureSize / 2); 82ce0e4b6b423e45f5a1c2eeedd8a5eff9d24f666eTeng-Hui Zhu if (!m_highEndGfx) 83ce0e4b6b423e45f5a1c2eeedd8a5eff9d24f666eTeng-Hui Zhu m_maxTextureAllocation = m_maxTextureAllocation / 2; 84ce0e4b6b423e45f5a1c2eeedd8a5eff9d24f666eTeng-Hui Zhu } 85ce0e4b6b423e45f5a1c2eeedd8a5eff9d24f666eTeng-Hui Zhu return m_maxTextureAllocation; 86522c8aecb5c6a797ceb59e8eaa9ab44e3a5fda54Shimeng (Simon) Wang} 87522c8aecb5c6a797ceb59e8eaa9ab44e3a5fda54Shimeng (Simon) Wang 88a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas RoardTilesManager::TilesManager() 8993bfc77abb66a95750b747cf5d782c31beadf7cfChris Craik : m_layerTexturesRemain(true) 90e1dfe84b38ed080c7bb7ac00fd9e3c6c590a147dTeng-Hui Zhu , m_highEndGfx(false) 91ce0e4b6b423e45f5a1c2eeedd8a5eff9d24f666eTeng-Hui Zhu , m_currentTextureCount(0) 92ce0e4b6b423e45f5a1c2eeedd8a5eff9d24f666eTeng-Hui Zhu , m_currentLayerTextureCount(0) 93ce0e4b6b423e45f5a1c2eeedd8a5eff9d24f666eTeng-Hui Zhu , m_maxTextureAllocation(-1) 94211482b53e73a386e2aabb0d3acb92e0e7ea22d4Nicolas Roard , m_generatorReady(false) 9503d850006e8ce54945fe44c36ffaf074143184c5Teng-Hui Zhu , m_showVisualIndicator(false) 96d2c2030045e0e26787ff8b9935d449e3be8a71ccJohn Reck , m_invertedScreen(false) 978852b0905b1a50ca045eb4bd19b2589aad663b5cTeng-Hui Zhu , m_useMinimalMemory(true) 98bac79a8ecce7b3aaf3bc4964957c9c59f163de38Chris Craik , m_useDoubleBuffering(true) 99d8be9016b7fda67a91b4ee17b3b2e7ba692ee553Chris Craik , m_contentUpdates(0) 100f7ad77dc2a981834d664fd24022c3dfade69c8aaChris Craik , m_webkitContentUpdates(0) 101451fcf2a39629f20f52ee6bb0294d217d8aa487fTeng-Hui Zhu , m_queue(0) 102808dc42f1e6a574778bc9e8bd41beb7bd9aef06fChris Craik , m_drawGLCount(1) 103c4718e6733cb345bafc3a95a9e1c234047bfde7eNicolas Roard , m_lastTimeLayersUsed(0) 104c4718e6733cb345bafc3a95a9e1c234047bfde7eNicolas Roard , m_hasLayerTextures(false) 1052ac76fe4e18c3325c8b3bb8f9435fdc7b96c0acaTeng-Hui Zhu , m_eglContext(EGL_NO_CONTEXT) 106a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas Roard{ 107d487c56b47c747d3e331ee1892e4c0473363afd2Chris Craik ALOGV("TilesManager ctor"); 1085ab250a6ffd49127ffe53059518204cfe5eea6f0Chris Craik m_textures.reserveCapacity(MAX_TEXTURE_ALLOCATION / 2); 1095ab250a6ffd49127ffe53059518204cfe5eea6f0Chris Craik m_availableTextures.reserveCapacity(MAX_TEXTURE_ALLOCATION / 2); 1105ab250a6ffd49127ffe53059518204cfe5eea6f0Chris Craik m_tilesTextures.reserveCapacity(MAX_TEXTURE_ALLOCATION / 2); 1115ab250a6ffd49127ffe53059518204cfe5eea6f0Chris Craik m_availableTilesTextures.reserveCapacity(MAX_TEXTURE_ALLOCATION / 2); 112334c36c686871998bf6c4ac958dfe3b3d5a87033Chris Craik 113334c36c686871998bf6c4ac958dfe3b3d5a87033Chris Craik m_textureGenerators = new sp<TexturesGenerator>[NUM_TEXTURES_GENERATORS]; 114334c36c686871998bf6c4ac958dfe3b3d5a87033Chris Craik for (int i = 0; i < NUM_TEXTURES_GENERATORS; i++) { 115334c36c686871998bf6c4ac958dfe3b3d5a87033Chris Craik m_textureGenerators[i] = new TexturesGenerator(this); 116334c36c686871998bf6c4ac958dfe3b3d5a87033Chris Craik ALOGD("Starting TG #%d, %p", i, m_textureGenerators[i].get()); 117334c36c686871998bf6c4ac958dfe3b3d5a87033Chris Craik m_textureGenerators[i]->run("TexturesGenerator"); 118334c36c686871998bf6c4ac958dfe3b3d5a87033Chris Craik } 119334c36c686871998bf6c4ac958dfe3b3d5a87033Chris Craik} 120334c36c686871998bf6c4ac958dfe3b3d5a87033Chris Craik 121334c36c686871998bf6c4ac958dfe3b3d5a87033Chris CraikTilesManager::~TilesManager() 122334c36c686871998bf6c4ac958dfe3b3d5a87033Chris Craik{ 123334c36c686871998bf6c4ac958dfe3b3d5a87033Chris Craik delete[] m_textureGenerators; 124a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas Roard} 125a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas Roard 126334c36c686871998bf6c4ac958dfe3b3d5a87033Chris Craik 127ce0e4b6b423e45f5a1c2eeedd8a5eff9d24f666eTeng-Hui Zhuvoid TilesManager::allocateTextures() 128a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas Roard{ 129ce0e4b6b423e45f5a1c2eeedd8a5eff9d24f666eTeng-Hui Zhu int nbTexturesToAllocate = m_currentTextureCount - m_textures.size(); 130ce0e4b6b423e45f5a1c2eeedd8a5eff9d24f666eTeng-Hui Zhu ALOGV("%d tiles to allocate (%d textures planned)", nbTexturesToAllocate, m_currentTextureCount); 1317e3773d591be20a4ddb1ef7df2709fd7655b7917Nicolas Roard int nbTexturesAllocated = 0; 1327e3773d591be20a4ddb1ef7df2709fd7655b7917Nicolas Roard for (int i = 0; i < nbTexturesToAllocate; i++) { 133594c6b805969c2673c84d1d1d1a3556ce376ac7aChris Craik TileTexture* texture = new TileTexture( 134ec182c75fb35d955a9115fbaf516f648a48ed0e1Derek Sollenberger tileWidth(), tileHeight()); 1357e3773d591be20a4ddb1ef7df2709fd7655b7917Nicolas Roard // the atomic load ensures that the texture has been fully initialized 1367e3773d591be20a4ddb1ef7df2709fd7655b7917Nicolas Roard // before we pass a pointer for other threads to operate on 137594c6b805969c2673c84d1d1d1a3556ce376ac7aChris Craik TileTexture* loadedTexture = 138594c6b805969c2673c84d1d1d1a3556ce376ac7aChris Craik reinterpret_cast<TileTexture*>( 1397e3773d591be20a4ddb1ef7df2709fd7655b7917Nicolas Roard android_atomic_acquire_load(reinterpret_cast<int32_t*>(&texture))); 1407e3773d591be20a4ddb1ef7df2709fd7655b7917Nicolas Roard m_textures.append(loadedTexture); 1417e3773d591be20a4ddb1ef7df2709fd7655b7917Nicolas Roard nbTexturesAllocated++; 142a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas Roard } 1433c131605fca8e29a88fdc4923d86bdc3f40adb2bNicolas Roard 144ce0e4b6b423e45f5a1c2eeedd8a5eff9d24f666eTeng-Hui Zhu int nbLayersTexturesToAllocate = m_currentLayerTextureCount - m_tilesTextures.size(); 145d487c56b47c747d3e331ee1892e4c0473363afd2Chris Craik ALOGV("%d layers tiles to allocate (%d textures planned)", 146ce0e4b6b423e45f5a1c2eeedd8a5eff9d24f666eTeng-Hui Zhu nbLayersTexturesToAllocate, m_currentLayerTextureCount); 14782b16301ec89989ef436f317f2f23f57ed2e2660Nicolas Roard int nbLayersTexturesAllocated = 0; 14882b16301ec89989ef436f317f2f23f57ed2e2660Nicolas Roard for (int i = 0; i < nbLayersTexturesToAllocate; i++) { 149594c6b805969c2673c84d1d1d1a3556ce376ac7aChris Craik TileTexture* texture = new TileTexture( 150c51715092b8d3be1b51cce8bae61750cbcf342c4Chris Craik tileWidth(), tileHeight()); 1513c131605fca8e29a88fdc4923d86bdc3f40adb2bNicolas Roard // the atomic load ensures that the texture has been fully initialized 1523c131605fca8e29a88fdc4923d86bdc3f40adb2bNicolas Roard // before we pass a pointer for other threads to operate on 153594c6b805969c2673c84d1d1d1a3556ce376ac7aChris Craik TileTexture* loadedTexture = 154594c6b805969c2673c84d1d1d1a3556ce376ac7aChris Craik reinterpret_cast<TileTexture*>( 1553c131605fca8e29a88fdc4923d86bdc3f40adb2bNicolas Roard android_atomic_acquire_load(reinterpret_cast<int32_t*>(&texture))); 1563c131605fca8e29a88fdc4923d86bdc3f40adb2bNicolas Roard m_tilesTextures.append(loadedTexture); 15782b16301ec89989ef436f317f2f23f57ed2e2660Nicolas Roard nbLayersTexturesAllocated++; 1583c131605fca8e29a88fdc4923d86bdc3f40adb2bNicolas Roard } 159d487c56b47c747d3e331ee1892e4c0473363afd2Chris Craik ALOGV("allocated %d textures for base (total: %d, %d Mb), %d textures for layers (total: %d, %d Mb)", 160d487c56b47c747d3e331ee1892e4c0473363afd2Chris Craik nbTexturesAllocated, m_textures.size(), 161d487c56b47c747d3e331ee1892e4c0473363afd2Chris Craik m_textures.size() * TILE_WIDTH * TILE_HEIGHT * 4 / 1024 / 1024, 162d487c56b47c747d3e331ee1892e4c0473363afd2Chris Craik nbLayersTexturesAllocated, m_tilesTextures.size(), 163c51715092b8d3be1b51cce8bae61750cbcf342c4Chris Craik m_tilesTextures.size() * tileWidth() * tileHeight() * 4 / 1024 / 1024); 164a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas Roard} 165a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas Roard 166a3a38731f4eeb01d2a42965b6c875d957999969dChris Craikvoid TilesManager::discardTextures(bool allTextures, bool glTextures) 1672986d27084d881dbe6f9c3ae35430a5978b7e659Chris Craik{ 1682986d27084d881dbe6f9c3ae35430a5978b7e659Chris Craik const unsigned int max = m_textures.size(); 1692986d27084d881dbe6f9c3ae35430a5978b7e659Chris Craik 1702986d27084d881dbe6f9c3ae35430a5978b7e659Chris Craik unsigned long long sparedDrawCount = ~0; // by default, spare no textures 1712986d27084d881dbe6f9c3ae35430a5978b7e659Chris Craik if (!allTextures) { 1722986d27084d881dbe6f9c3ae35430a5978b7e659Chris Craik // if we're not deallocating all textures, spare those with max drawcount 1732986d27084d881dbe6f9c3ae35430a5978b7e659Chris Craik sparedDrawCount = 0; 1742986d27084d881dbe6f9c3ae35430a5978b7e659Chris Craik for (unsigned int i = 0; i < max; i++) { 1752986d27084d881dbe6f9c3ae35430a5978b7e659Chris Craik TextureOwner* owner = m_textures[i]->owner(); 1762986d27084d881dbe6f9c3ae35430a5978b7e659Chris Craik if (owner) 1772986d27084d881dbe6f9c3ae35430a5978b7e659Chris Craik sparedDrawCount = std::max(sparedDrawCount, owner->drawCount()); 1782986d27084d881dbe6f9c3ae35430a5978b7e659Chris Craik } 1792986d27084d881dbe6f9c3ae35430a5978b7e659Chris Craik } 180a3a38731f4eeb01d2a42965b6c875d957999969dChris Craik discardTexturesVector(sparedDrawCount, m_textures, glTextures); 181a3a38731f4eeb01d2a42965b6c875d957999969dChris Craik discardTexturesVector(sparedDrawCount, m_tilesTextures, glTextures); 182c4718e6733cb345bafc3a95a9e1c234047bfde7eNicolas Roard} 1832986d27084d881dbe6f9c3ae35430a5978b7e659Chris Craik 1842ac76fe4e18c3325c8b3bb8f9435fdc7b96c0acaTeng-Hui Zhuvoid TilesManager::markAllGLTexturesZero() 1852ac76fe4e18c3325c8b3bb8f9435fdc7b96c0acaTeng-Hui Zhu{ 1862ac76fe4e18c3325c8b3bb8f9435fdc7b96c0acaTeng-Hui Zhu for (unsigned int i = 0; i < m_textures.size(); i++) 1872ac76fe4e18c3325c8b3bb8f9435fdc7b96c0acaTeng-Hui Zhu m_textures[i]->m_ownTextureId = 0; 1882ac76fe4e18c3325c8b3bb8f9435fdc7b96c0acaTeng-Hui Zhu for (unsigned int i = 0; i < m_tilesTextures.size(); i++) 1892ac76fe4e18c3325c8b3bb8f9435fdc7b96c0acaTeng-Hui Zhu m_tilesTextures[i]->m_ownTextureId = 0; 1902ac76fe4e18c3325c8b3bb8f9435fdc7b96c0acaTeng-Hui Zhu} 1912ac76fe4e18c3325c8b3bb8f9435fdc7b96c0acaTeng-Hui Zhu 192a3a38731f4eeb01d2a42965b6c875d957999969dChris Craikvoid TilesManager::discardTexturesVector(unsigned long long sparedDrawCount, 193594c6b805969c2673c84d1d1d1a3556ce376ac7aChris Craik WTF::Vector<TileTexture*>& textures, 194a3a38731f4eeb01d2a42965b6c875d957999969dChris Craik bool deallocateGLTextures) 195c4718e6733cb345bafc3a95a9e1c234047bfde7eNicolas Roard{ 196c4718e6733cb345bafc3a95a9e1c234047bfde7eNicolas Roard const unsigned int max = textures.size(); 1972986d27084d881dbe6f9c3ae35430a5978b7e659Chris Craik int dealloc = 0; 19850359a67e1503b5d416cae7e64d46e3f3389442aTeng-Hui Zhu WTF::Vector<int> discardedIndex; 1992986d27084d881dbe6f9c3ae35430a5978b7e659Chris Craik for (unsigned int i = 0; i < max; i++) { 200c4718e6733cb345bafc3a95a9e1c234047bfde7eNicolas Roard TextureOwner* owner = textures[i]->owner(); 2012986d27084d881dbe6f9c3ae35430a5978b7e659Chris Craik if (!owner || owner->drawCount() < sparedDrawCount) { 202a3a38731f4eeb01d2a42965b6c875d957999969dChris Craik if (deallocateGLTextures) { 203a3a38731f4eeb01d2a42965b6c875d957999969dChris Craik // deallocate textures' gl memory 204a3a38731f4eeb01d2a42965b6c875d957999969dChris Craik textures[i]->discardGLTexture(); 20550359a67e1503b5d416cae7e64d46e3f3389442aTeng-Hui Zhu discardedIndex.append(i); 206a3a38731f4eeb01d2a42965b6c875d957999969dChris Craik } else if (owner) { 207a3a38731f4eeb01d2a42965b6c875d957999969dChris Craik // simply detach textures from owner 208594c6b805969c2673c84d1d1d1a3556ce376ac7aChris Craik static_cast<Tile*>(owner)->discardTextures(); 209a3a38731f4eeb01d2a42965b6c875d957999969dChris Craik } 2102986d27084d881dbe6f9c3ae35430a5978b7e659Chris Craik dealloc++; 2112986d27084d881dbe6f9c3ae35430a5978b7e659Chris Craik } 2122986d27084d881dbe6f9c3ae35430a5978b7e659Chris Craik } 21350359a67e1503b5d416cae7e64d46e3f3389442aTeng-Hui Zhu 21450359a67e1503b5d416cae7e64d46e3f3389442aTeng-Hui Zhu bool base = textures == m_textures; 215594c6b805969c2673c84d1d1d1a3556ce376ac7aChris Craik // Clean up the vector of TileTextures and reset the max texture count. 21650359a67e1503b5d416cae7e64d46e3f3389442aTeng-Hui Zhu if (discardedIndex.size()) { 21750359a67e1503b5d416cae7e64d46e3f3389442aTeng-Hui Zhu android::Mutex::Autolock lock(m_texturesLock); 21850359a67e1503b5d416cae7e64d46e3f3389442aTeng-Hui Zhu for (int i = discardedIndex.size() - 1; i >= 0; i--) 21950359a67e1503b5d416cae7e64d46e3f3389442aTeng-Hui Zhu textures.remove(discardedIndex[i]); 22050359a67e1503b5d416cae7e64d46e3f3389442aTeng-Hui Zhu 22150359a67e1503b5d416cae7e64d46e3f3389442aTeng-Hui Zhu int remainedTextureNumber = textures.size(); 222ce0e4b6b423e45f5a1c2eeedd8a5eff9d24f666eTeng-Hui Zhu int* countPtr = base ? &m_currentTextureCount : &m_currentLayerTextureCount; 22350359a67e1503b5d416cae7e64d46e3f3389442aTeng-Hui Zhu if (remainedTextureNumber < *countPtr) { 224ce0e4b6b423e45f5a1c2eeedd8a5eff9d24f666eTeng-Hui Zhu ALOGV("reset currentTextureCount for %s tiles from %d to %d", 225d487c56b47c747d3e331ee1892e4c0473363afd2Chris Craik base ? "base" : "layer", *countPtr, remainedTextureNumber); 22650359a67e1503b5d416cae7e64d46e3f3389442aTeng-Hui Zhu *countPtr = remainedTextureNumber; 22750359a67e1503b5d416cae7e64d46e3f3389442aTeng-Hui Zhu } 22850359a67e1503b5d416cae7e64d46e3f3389442aTeng-Hui Zhu 22950359a67e1503b5d416cae7e64d46e3f3389442aTeng-Hui Zhu } 23050359a67e1503b5d416cae7e64d46e3f3389442aTeng-Hui Zhu 231d487c56b47c747d3e331ee1892e4c0473363afd2Chris Craik ALOGV("Discarded %d %s textures (out of %d %s tiles)", 232d487c56b47c747d3e331ee1892e4c0473363afd2Chris Craik dealloc, (deallocateGLTextures ? "gl" : ""), 233d487c56b47c747d3e331ee1892e4c0473363afd2Chris Craik max, base ? "base" : "layer"); 2342986d27084d881dbe6f9c3ae35430a5978b7e659Chris Craik} 2352986d27084d881dbe6f9c3ae35430a5978b7e659Chris Craik 23654e75f0875a8376c1119b019431921bc58295b79Nicolas Roardvoid TilesManager::gatherTexturesNumbers(int* nbTextures, int* nbAllocatedTextures, 23754e75f0875a8376c1119b019431921bc58295b79Nicolas Roard int* nbLayerTextures, int* nbAllocatedLayerTextures) 23854e75f0875a8376c1119b019431921bc58295b79Nicolas Roard{ 23954e75f0875a8376c1119b019431921bc58295b79Nicolas Roard *nbTextures = m_textures.size(); 24054e75f0875a8376c1119b019431921bc58295b79Nicolas Roard for (unsigned int i = 0; i < m_textures.size(); i++) { 241594c6b805969c2673c84d1d1d1a3556ce376ac7aChris Craik TileTexture* texture = m_textures[i]; 24254e75f0875a8376c1119b019431921bc58295b79Nicolas Roard if (texture->m_ownTextureId) 24354e75f0875a8376c1119b019431921bc58295b79Nicolas Roard *nbAllocatedTextures += 1; 24454e75f0875a8376c1119b019431921bc58295b79Nicolas Roard } 24554e75f0875a8376c1119b019431921bc58295b79Nicolas Roard *nbLayerTextures = m_tilesTextures.size(); 24654e75f0875a8376c1119b019431921bc58295b79Nicolas Roard for (unsigned int i = 0; i < m_tilesTextures.size(); i++) { 247594c6b805969c2673c84d1d1d1a3556ce376ac7aChris Craik TileTexture* texture = m_tilesTextures[i]; 24854e75f0875a8376c1119b019431921bc58295b79Nicolas Roard if (texture->m_ownTextureId) 24954e75f0875a8376c1119b019431921bc58295b79Nicolas Roard *nbAllocatedLayerTextures += 1; 25054e75f0875a8376c1119b019431921bc58295b79Nicolas Roard } 25154e75f0875a8376c1119b019431921bc58295b79Nicolas Roard} 25254e75f0875a8376c1119b019431921bc58295b79Nicolas Roard 253bd3f93b66934582acd0b6c70bcf60ca643b36eadChris Craikvoid TilesManager::dirtyTexturesVector(WTF::Vector<TileTexture*>& textures) 254bd3f93b66934582acd0b6c70bcf60ca643b36eadChris Craik{ 255bd3f93b66934582acd0b6c70bcf60ca643b36eadChris Craik for (unsigned int i = 0; i < textures.size(); i++) { 256bd3f93b66934582acd0b6c70bcf60ca643b36eadChris Craik Tile* currentOwner = static_cast<Tile*>(textures[i]->owner()); 257bd3f93b66934582acd0b6c70bcf60ca643b36eadChris Craik if (currentOwner) 258bd3f93b66934582acd0b6c70bcf60ca643b36eadChris Craik currentOwner->markAsDirty(); 259bd3f93b66934582acd0b6c70bcf60ca643b36eadChris Craik } 260bd3f93b66934582acd0b6c70bcf60ca643b36eadChris Craik} 261bd3f93b66934582acd0b6c70bcf60ca643b36eadChris Craik 262bd3f93b66934582acd0b6c70bcf60ca643b36eadChris Craikvoid TilesManager::dirtyAllTiles() 263bd3f93b66934582acd0b6c70bcf60ca643b36eadChris Craik{ 264bd3f93b66934582acd0b6c70bcf60ca643b36eadChris Craik dirtyTexturesVector(m_textures); 265bd3f93b66934582acd0b6c70bcf60ca643b36eadChris Craik dirtyTexturesVector(m_tilesTextures); 266bd3f93b66934582acd0b6c70bcf60ca643b36eadChris Craik} 267bd3f93b66934582acd0b6c70bcf60ca643b36eadChris Craik 268a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas Roardvoid TilesManager::printTextures() 269a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas Roard{ 270a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas Roard#ifdef DEBUG 271d487c56b47c747d3e331ee1892e4c0473363afd2Chris Craik ALOGV("++++++"); 272a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas Roard for (unsigned int i = 0; i < m_textures.size(); i++) { 273594c6b805969c2673c84d1d1d1a3556ce376ac7aChris Craik TileTexture* texture = m_textures[i]; 274594c6b805969c2673c84d1d1d1a3556ce376ac7aChris Craik Tile* o = 0; 275a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas Roard if (texture->owner()) 276594c6b805969c2673c84d1d1d1a3556ce376ac7aChris Craik o = (Tile*) texture->owner(); 277a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas Roard int x = -1; 278a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas Roard int y = -1; 279a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas Roard if (o) { 280a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas Roard x = o->x(); 281a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas Roard y = o->y(); 282a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas Roard } 2837b4a179bde698a856bed54a680438a9db3ff0566Chris Craik ALOGV("[%d] texture %x owner: %x (%d, %d) scale: %.2f", 2847b4a179bde698a856bed54a680438a9db3ff0566Chris Craik i, texture, o, x, y, o ? o->scale() : 0); 285a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas Roard } 286d487c56b47c747d3e331ee1892e4c0473363afd2Chris Craik ALOGV("------"); 287a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas Roard#endif // DEBUG 288a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas Roard} 289a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas Roard 290b7d8e1b710ce418ca1d8b7fc3612740757fd1aecNicolas Roardvoid TilesManager::gatherTextures() 291b7d8e1b710ce418ca1d8b7fc3612740757fd1aecNicolas Roard{ 292b7d8e1b710ce418ca1d8b7fc3612740757fd1aecNicolas Roard android::Mutex::Autolock lock(m_texturesLock); 293b7d8e1b710ce418ca1d8b7fc3612740757fd1aecNicolas Roard m_availableTextures = m_textures; 294b7d8e1b710ce418ca1d8b7fc3612740757fd1aecNicolas Roard m_availableTilesTextures = m_tilesTextures; 29593bfc77abb66a95750b747cf5d782c31beadf7cfChris Craik m_layerTexturesRemain = true; 296b7d8e1b710ce418ca1d8b7fc3612740757fd1aecNicolas Roard} 297b7d8e1b710ce418ca1d8b7fc3612740757fd1aecNicolas Roard 298594c6b805969c2673c84d1d1d1a3556ce376ac7aChris CraikTileTexture* TilesManager::getAvailableTexture(Tile* owner) 299a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas Roard{ 300a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas Roard android::Mutex::Autolock lock(m_texturesLock); 301610686734abc1ecfc43ab4e02289ac713fe76f1fDerek Sollenberger 302594c6b805969c2673c84d1d1d1a3556ce376ac7aChris Craik WTF::Vector<TileTexture*>* availableTexturePool; 303e080317b90534632e8be18dc8d5e9a51554b444aChris Craik if (owner->isLayerTile()) 3048ad3ab0e47f0d5039e89c1873c178f538ec1b0dfChris Craik availableTexturePool = &m_availableTilesTextures; 305e080317b90534632e8be18dc8d5e9a51554b444aChris Craik else 3068ad3ab0e47f0d5039e89c1873c178f538ec1b0dfChris Craik availableTexturePool = &m_availableTextures; 307e080317b90534632e8be18dc8d5e9a51554b444aChris Craik 308e080317b90534632e8be18dc8d5e9a51554b444aChris Craik // Sanity check that the tile does not already own a texture 309e080317b90534632e8be18dc8d5e9a51554b444aChris Craik if (owner->backTexture() && owner->backTexture()->owner() == owner) { 31086ceef033ca2c835916e3970c2ea7cfdba5856a3Chris Craik int removeIndex = availableTexturePool->find(owner->backTexture()); 31186ceef033ca2c835916e3970c2ea7cfdba5856a3Chris Craik 31286ceef033ca2c835916e3970c2ea7cfdba5856a3Chris Craik // TODO: investigate why texture isn't found 31386ceef033ca2c835916e3970c2ea7cfdba5856a3Chris Craik if (removeIndex >= 0) 31486ceef033ca2c835916e3970c2ea7cfdba5856a3Chris Craik availableTexturePool->remove(removeIndex); 315e080317b90534632e8be18dc8d5e9a51554b444aChris Craik return owner->backTexture(); 3163c131605fca8e29a88fdc4923d86bdc3f40adb2bNicolas Roard } 3173c131605fca8e29a88fdc4923d86bdc3f40adb2bNicolas Roard 318610686734abc1ecfc43ab4e02289ac713fe76f1fDerek Sollenberger // The heuristic for selecting a texture is as follows: 3196aa089bded6a1abbf8d61264588e1e3a32be31b3Chris Craik // 1. Skip textures currently being painted, they can't be painted while 3206aa089bded6a1abbf8d61264588e1e3a32be31b3Chris Craik // busy anyway 3216aa089bded6a1abbf8d61264588e1e3a32be31b3Chris Craik // 2. If a tile isn't owned, break with that one 3226aa089bded6a1abbf8d61264588e1e3a32be31b3Chris Craik // 3. Don't let tiles acquire their front textures 323d8be9016b7fda67a91b4ee17b3b2e7ba692ee553Chris Craik // 4. Otherwise, use the least recently prepared tile, but ignoring tiles 324ab3df5899158b0bcb5c7bb6858d9717a22781ad3Chris Craik // drawn in the last frame to avoid flickering 32572a76070d36a51926c224d230f1503c46f30da60Chris Craik 326594c6b805969c2673c84d1d1d1a3556ce376ac7aChris Craik TileTexture* farthestTexture = 0; 327ab3df5899158b0bcb5c7bb6858d9717a22781ad3Chris Craik unsigned long long oldestDrawCount = getDrawGLCount() - 1; 3288ad3ab0e47f0d5039e89c1873c178f538ec1b0dfChris Craik const unsigned int max = availableTexturePool->size(); 329a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas Roard for (unsigned int i = 0; i < max; i++) { 330594c6b805969c2673c84d1d1d1a3556ce376ac7aChris Craik TileTexture* texture = (*availableTexturePool)[i]; 331594c6b805969c2673c84d1d1d1a3556ce376ac7aChris Craik Tile* currentOwner = static_cast<Tile*>(texture->owner()); 3328ad3ab0e47f0d5039e89c1873c178f538ec1b0dfChris Craik if (!currentOwner) { 3336aa089bded6a1abbf8d61264588e1e3a32be31b3Chris Craik // unused texture! take it! 334a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas Roard farthestTexture = texture; 335a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas Roard break; 336a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas Roard } 33772a76070d36a51926c224d230f1503c46f30da60Chris Craik 3386aa089bded6a1abbf8d61264588e1e3a32be31b3Chris Craik if (currentOwner == owner) { 3396aa089bded6a1abbf8d61264588e1e3a32be31b3Chris Craik // Don't let a tile acquire its own front texture, as the 3406aa089bded6a1abbf8d61264588e1e3a32be31b3Chris Craik // acquisition logic doesn't handle that 341808dc42f1e6a574778bc9e8bd41beb7bd9aef06fChris Craik continue; 3426aa089bded6a1abbf8d61264588e1e3a32be31b3Chris Craik } 343808dc42f1e6a574778bc9e8bd41beb7bd9aef06fChris Craik 3448ad3ab0e47f0d5039e89c1873c178f538ec1b0dfChris Craik unsigned long long textureDrawCount = currentOwner->drawCount(); 3458ad3ab0e47f0d5039e89c1873c178f538ec1b0dfChris Craik if (oldestDrawCount > textureDrawCount) { 346a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas Roard farthestTexture = texture; 3478ad3ab0e47f0d5039e89c1873c178f538ec1b0dfChris Craik oldestDrawCount = textureDrawCount; 348a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas Roard } 349a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas Roard } 35072a76070d36a51926c224d230f1503c46f30da60Chris Craik 351ab3df5899158b0bcb5c7bb6858d9717a22781ad3Chris Craik if (farthestTexture) { 352594c6b805969c2673c84d1d1d1a3556ce376ac7aChris Craik Tile* previousOwner = static_cast<Tile*>(farthestTexture->owner()); 353ab3df5899158b0bcb5c7bb6858d9717a22781ad3Chris Craik if (farthestTexture->acquire(owner)) { 354ab3df5899158b0bcb5c7bb6858d9717a22781ad3Chris Craik if (previousOwner) { 355f6a40880028cf495025747229c627f42e25acc66Chris Craik previousOwner->removeTexture(farthestTexture); 356f6a40880028cf495025747229c627f42e25acc66Chris Craik 357d487c56b47c747d3e331ee1892e4c0473363afd2Chris Craik ALOGV("%s texture %p stolen from tile %d, %d for %d, %d, drawCount was %llu (now %llu)", 358d487c56b47c747d3e331ee1892e4c0473363afd2Chris Craik owner->isLayerTile() ? "LAYER" : "BASE", 359d487c56b47c747d3e331ee1892e4c0473363afd2Chris Craik farthestTexture, previousOwner->x(), previousOwner->y(), 360d487c56b47c747d3e331ee1892e4c0473363afd2Chris Craik owner->x(), owner->y(), 361d487c56b47c747d3e331ee1892e4c0473363afd2Chris Craik oldestDrawCount, getDrawGLCount()); 362ab3df5899158b0bcb5c7bb6858d9717a22781ad3Chris Craik } 363ab3df5899158b0bcb5c7bb6858d9717a22781ad3Chris Craik 364ab3df5899158b0bcb5c7bb6858d9717a22781ad3Chris Craik availableTexturePool->remove(availableTexturePool->find(farthestTexture)); 365ab3df5899158b0bcb5c7bb6858d9717a22781ad3Chris Craik return farthestTexture; 3668ad3ab0e47f0d5039e89c1873c178f538ec1b0dfChris Craik } 36793bfc77abb66a95750b747cf5d782c31beadf7cfChris Craik } else { 36893bfc77abb66a95750b747cf5d782c31beadf7cfChris Craik if (owner->isLayerTile()) { 36993bfc77abb66a95750b747cf5d782c31beadf7cfChris Craik // couldn't find a tile for a layer, layers shouldn't request redraw 37093bfc77abb66a95750b747cf5d782c31beadf7cfChris Craik // TODO: once we do layer prefetching, don't set this for those 37193bfc77abb66a95750b747cf5d782c31beadf7cfChris Craik // tiles 37293bfc77abb66a95750b747cf5d782c31beadf7cfChris Craik m_layerTexturesRemain = false; 37393bfc77abb66a95750b747cf5d782c31beadf7cfChris Craik } 374a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas Roard } 375610686734abc1ecfc43ab4e02289ac713fe76f1fDerek Sollenberger 376d487c56b47c747d3e331ee1892e4c0473363afd2Chris Craik ALOGV("Couldn't find an available texture for %s tile %x (%d, %d) out of %d available", 377808dc42f1e6a574778bc9e8bd41beb7bd9aef06fChris Craik owner->isLayerTile() ? "LAYER" : "BASE", 3788ad3ab0e47f0d5039e89c1873c178f538ec1b0dfChris Craik owner, owner->x(), owner->y(), max); 379a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas Roard#ifdef DEBUG 380a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas Roard printTextures(); 381a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas Roard#endif // DEBUG 382a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas Roard return 0; 383a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas Roard} 384a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas Roard 385e1dfe84b38ed080c7bb7ac00fd9e3c6c590a147dTeng-Hui Zhuvoid TilesManager::setHighEndGfx(bool highEnd) 386e1dfe84b38ed080c7bb7ac00fd9e3c6c590a147dTeng-Hui Zhu{ 387e1dfe84b38ed080c7bb7ac00fd9e3c6c590a147dTeng-Hui Zhu m_highEndGfx = highEnd; 388e1dfe84b38ed080c7bb7ac00fd9e3c6c590a147dTeng-Hui Zhu} 389e1dfe84b38ed080c7bb7ac00fd9e3c6c590a147dTeng-Hui Zhu 390e1dfe84b38ed080c7bb7ac00fd9e3c6c590a147dTeng-Hui Zhubool TilesManager::highEndGfx() 391e1dfe84b38ed080c7bb7ac00fd9e3c6c590a147dTeng-Hui Zhu{ 392e1dfe84b38ed080c7bb7ac00fd9e3c6c590a147dTeng-Hui Zhu return m_highEndGfx; 393e1dfe84b38ed080c7bb7ac00fd9e3c6c590a147dTeng-Hui Zhu} 394e1dfe84b38ed080c7bb7ac00fd9e3c6c590a147dTeng-Hui Zhu 395ce0e4b6b423e45f5a1c2eeedd8a5eff9d24f666eTeng-Hui Zhuint TilesManager::currentTextureCount() 396a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas Roard{ 3977e3773d591be20a4ddb1ef7df2709fd7655b7917Nicolas Roard android::Mutex::Autolock lock(m_texturesLock); 398ce0e4b6b423e45f5a1c2eeedd8a5eff9d24f666eTeng-Hui Zhu return m_currentTextureCount; 3997e3773d591be20a4ddb1ef7df2709fd7655b7917Nicolas Roard} 4007e3773d591be20a4ddb1ef7df2709fd7655b7917Nicolas Roard 401ce0e4b6b423e45f5a1c2eeedd8a5eff9d24f666eTeng-Hui Zhuint TilesManager::currentLayerTextureCount() 402c4718e6733cb345bafc3a95a9e1c234047bfde7eNicolas Roard{ 403c4718e6733cb345bafc3a95a9e1c234047bfde7eNicolas Roard android::Mutex::Autolock lock(m_texturesLock); 404ce0e4b6b423e45f5a1c2eeedd8a5eff9d24f666eTeng-Hui Zhu return m_currentLayerTextureCount; 405c4718e6733cb345bafc3a95a9e1c234047bfde7eNicolas Roard} 406c4718e6733cb345bafc3a95a9e1c234047bfde7eNicolas Roard 407ce0e4b6b423e45f5a1c2eeedd8a5eff9d24f666eTeng-Hui Zhuvoid TilesManager::setCurrentTextureCount(int newTextureCount) 4087e3773d591be20a4ddb1ef7df2709fd7655b7917Nicolas Roard{ 409ce0e4b6b423e45f5a1c2eeedd8a5eff9d24f666eTeng-Hui Zhu int maxTextureAllocation = getMaxTextureAllocation(); 410ce0e4b6b423e45f5a1c2eeedd8a5eff9d24f666eTeng-Hui Zhu ALOGV("setCurrentTextureCount: %d (current: %d, max:%d)", 411ce0e4b6b423e45f5a1c2eeedd8a5eff9d24f666eTeng-Hui Zhu newTextureCount, m_currentTextureCount, maxTextureAllocation); 412ce0e4b6b423e45f5a1c2eeedd8a5eff9d24f666eTeng-Hui Zhu if (m_currentTextureCount == maxTextureAllocation || 413ce0e4b6b423e45f5a1c2eeedd8a5eff9d24f666eTeng-Hui Zhu newTextureCount <= m_currentTextureCount) 4147e3773d591be20a4ddb1ef7df2709fd7655b7917Nicolas Roard return; 4157e3773d591be20a4ddb1ef7df2709fd7655b7917Nicolas Roard 4167e3773d591be20a4ddb1ef7df2709fd7655b7917Nicolas Roard android::Mutex::Autolock lock(m_texturesLock); 417ce0e4b6b423e45f5a1c2eeedd8a5eff9d24f666eTeng-Hui Zhu m_currentTextureCount = std::min(newTextureCount, maxTextureAllocation); 41840dbb7e9ff961829a7f4402ab8657c622ec2e9f6Nicolas Roard 419ce0e4b6b423e45f5a1c2eeedd8a5eff9d24f666eTeng-Hui Zhu allocateTextures(); 420a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas Roard} 421a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas Roard 422ce0e4b6b423e45f5a1c2eeedd8a5eff9d24f666eTeng-Hui Zhuvoid TilesManager::setCurrentLayerTextureCount(int newTextureCount) 423c4718e6733cb345bafc3a95a9e1c234047bfde7eNicolas Roard{ 424ce0e4b6b423e45f5a1c2eeedd8a5eff9d24f666eTeng-Hui Zhu int maxTextureAllocation = getMaxTextureAllocation(); 425ce0e4b6b423e45f5a1c2eeedd8a5eff9d24f666eTeng-Hui Zhu ALOGV("setCurrentLayerTextureCount: %d (current: %d, max:%d)", 426ce0e4b6b423e45f5a1c2eeedd8a5eff9d24f666eTeng-Hui Zhu newTextureCount, m_currentLayerTextureCount, maxTextureAllocation); 427ce0e4b6b423e45f5a1c2eeedd8a5eff9d24f666eTeng-Hui Zhu if (!newTextureCount && m_hasLayerTextures) { 428c4718e6733cb345bafc3a95a9e1c234047bfde7eNicolas Roard double secondsSinceLayersUsed = WTF::currentTime() - m_lastTimeLayersUsed; 429c4718e6733cb345bafc3a95a9e1c234047bfde7eNicolas Roard if (secondsSinceLayersUsed > LAYER_TEXTURES_DESTROY_TIMEOUT) { 430c4718e6733cb345bafc3a95a9e1c234047bfde7eNicolas Roard unsigned long long sparedDrawCount = ~0; // by default, spare no textures 431a3a38731f4eeb01d2a42965b6c875d957999969dChris Craik bool deleteGLTextures = true; 432a3a38731f4eeb01d2a42965b6c875d957999969dChris Craik discardTexturesVector(sparedDrawCount, m_tilesTextures, deleteGLTextures); 433c4718e6733cb345bafc3a95a9e1c234047bfde7eNicolas Roard m_hasLayerTextures = false; 434c4718e6733cb345bafc3a95a9e1c234047bfde7eNicolas Roard } 435c4718e6733cb345bafc3a95a9e1c234047bfde7eNicolas Roard return; 436c4718e6733cb345bafc3a95a9e1c234047bfde7eNicolas Roard } 437c4718e6733cb345bafc3a95a9e1c234047bfde7eNicolas Roard m_lastTimeLayersUsed = WTF::currentTime(); 438ce0e4b6b423e45f5a1c2eeedd8a5eff9d24f666eTeng-Hui Zhu if (m_currentLayerTextureCount == maxTextureAllocation || 439ce0e4b6b423e45f5a1c2eeedd8a5eff9d24f666eTeng-Hui Zhu newTextureCount <= m_currentLayerTextureCount) 440c4718e6733cb345bafc3a95a9e1c234047bfde7eNicolas Roard return; 441c4718e6733cb345bafc3a95a9e1c234047bfde7eNicolas Roard 442c4718e6733cb345bafc3a95a9e1c234047bfde7eNicolas Roard android::Mutex::Autolock lock(m_texturesLock); 443ce0e4b6b423e45f5a1c2eeedd8a5eff9d24f666eTeng-Hui Zhu m_currentLayerTextureCount = std::min(newTextureCount, maxTextureAllocation); 444c4718e6733cb345bafc3a95a9e1c234047bfde7eNicolas Roard 445ce0e4b6b423e45f5a1c2eeedd8a5eff9d24f666eTeng-Hui Zhu allocateTextures(); 446c4718e6733cb345bafc3a95a9e1c234047bfde7eNicolas Roard m_hasLayerTextures = true; 447c4718e6733cb345bafc3a95a9e1c234047bfde7eNicolas Roard} 448c4718e6733cb345bafc3a95a9e1c234047bfde7eNicolas Roard 449451fcf2a39629f20f52ee6bb0294d217d8aa487fTeng-Hui ZhuTransferQueue* TilesManager::transferQueue() 450451fcf2a39629f20f52ee6bb0294d217d8aa487fTeng-Hui Zhu{ 4517a09d1cde40c92dfd028e68ca2408478b9fe152bJohn Reck // m_queue will be created on the UI thread, although it may 4527a09d1cde40c92dfd028e68ca2408478b9fe152bJohn Reck // be accessed from the TexturesGenerator. However, that can only happen after 4537a09d1cde40c92dfd028e68ca2408478b9fe152bJohn Reck // a previous transferQueue() call due to a prepare. 454451fcf2a39629f20f52ee6bb0294d217d8aa487fTeng-Hui Zhu if (!m_queue) 455a464817e995321cae99f09266e27d4fa322d9b31Chris Craik m_queue = new TransferQueue(m_useMinimalMemory && !m_highEndGfx); 456451fcf2a39629f20f52ee6bb0294d217d8aa487fTeng-Hui Zhu return m_queue; 457451fcf2a39629f20f52ee6bb0294d217d8aa487fTeng-Hui Zhu} 458c4718e6733cb345bafc3a95a9e1c234047bfde7eNicolas Roard 4592ac76fe4e18c3325c8b3bb8f9435fdc7b96c0acaTeng-Hui Zhu// When GL context changed or we get a low memory signal, we want to cleanup all 4602ac76fe4e18c3325c8b3bb8f9435fdc7b96c0acaTeng-Hui Zhu// the GPU memory webview is using. 4612ac76fe4e18c3325c8b3bb8f9435fdc7b96c0acaTeng-Hui Zhu// The recreation will be on the next incoming draw call at the drawGL of 4622ac76fe4e18c3325c8b3bb8f9435fdc7b96c0acaTeng-Hui Zhu// GLWebViewState or the VideoLayerAndroid 4632ac76fe4e18c3325c8b3bb8f9435fdc7b96c0acaTeng-Hui Zhuvoid TilesManager::cleanupGLResources() 4642ac76fe4e18c3325c8b3bb8f9435fdc7b96c0acaTeng-Hui Zhu{ 4652ac76fe4e18c3325c8b3bb8f9435fdc7b96c0acaTeng-Hui Zhu transferQueue()->cleanupGLResourcesAndQueue(); 4662ac76fe4e18c3325c8b3bb8f9435fdc7b96c0acaTeng-Hui Zhu shader()->cleanupGLResources(); 4672ac76fe4e18c3325c8b3bb8f9435fdc7b96c0acaTeng-Hui Zhu videoLayerManager()->cleanupGLResources(); 4682ac76fe4e18c3325c8b3bb8f9435fdc7b96c0acaTeng-Hui Zhu m_eglContext = EGL_NO_CONTEXT; 4692ac76fe4e18c3325c8b3bb8f9435fdc7b96c0acaTeng-Hui Zhu GLUtils::checkGlError("TilesManager::cleanupGLResources"); 4702ac76fe4e18c3325c8b3bb8f9435fdc7b96c0acaTeng-Hui Zhu} 4712ac76fe4e18c3325c8b3bb8f9435fdc7b96c0acaTeng-Hui Zhu 4722ac76fe4e18c3325c8b3bb8f9435fdc7b96c0acaTeng-Hui Zhuvoid TilesManager::updateTilesIfContextVerified() 4732ac76fe4e18c3325c8b3bb8f9435fdc7b96c0acaTeng-Hui Zhu{ 4746c4c0302dd154e5090966c57bb4b6b216644fb01Teng-Hui Zhu EGLContext ctx = eglGetCurrentContext(); 4756c4c0302dd154e5090966c57bb4b6b216644fb01Teng-Hui Zhu GLUtils::checkEglError("contextChanged"); 4766c4c0302dd154e5090966c57bb4b6b216644fb01Teng-Hui Zhu if (ctx != m_eglContext) { 4776c4c0302dd154e5090966c57bb4b6b216644fb01Teng-Hui Zhu if (m_eglContext != EGL_NO_CONTEXT) { 4786c4c0302dd154e5090966c57bb4b6b216644fb01Teng-Hui Zhu // A change in EGL context is an unexpected error, but we don't want to 4796c4c0302dd154e5090966c57bb4b6b216644fb01Teng-Hui Zhu // crash or ANR. Therefore, abandon the Surface Texture and GL resources; 4806c4c0302dd154e5090966c57bb4b6b216644fb01Teng-Hui Zhu // they'll be recreated later in setupDrawing. (We can't delete them 4816c4c0302dd154e5090966c57bb4b6b216644fb01Teng-Hui Zhu // since the context is gone) 4826c4c0302dd154e5090966c57bb4b6b216644fb01Teng-Hui Zhu ALOGE("Unexpected : EGLContext changed! current %x , expected %x", 4836c4c0302dd154e5090966c57bb4b6b216644fb01Teng-Hui Zhu ctx, m_eglContext); 4846c4c0302dd154e5090966c57bb4b6b216644fb01Teng-Hui Zhu transferQueue()->resetQueue(); 4856c4c0302dd154e5090966c57bb4b6b216644fb01Teng-Hui Zhu shader()->forceNeedsInit(); 4866c4c0302dd154e5090966c57bb4b6b216644fb01Teng-Hui Zhu videoLayerManager()->forceNeedsInit(); 4876c4c0302dd154e5090966c57bb4b6b216644fb01Teng-Hui Zhu markAllGLTexturesZero(); 4886c4c0302dd154e5090966c57bb4b6b216644fb01Teng-Hui Zhu } else { 4896c4c0302dd154e5090966c57bb4b6b216644fb01Teng-Hui Zhu // This is the first time we went into this new EGL context. 4906c4c0302dd154e5090966c57bb4b6b216644fb01Teng-Hui Zhu // We will have the GL resources to be re-inited and we can't update 4916c4c0302dd154e5090966c57bb4b6b216644fb01Teng-Hui Zhu // dirty tiles yet. 4926c4c0302dd154e5090966c57bb4b6b216644fb01Teng-Hui Zhu ALOGD("new EGLContext from framework: %x ", ctx); 4936c4c0302dd154e5090966c57bb4b6b216644fb01Teng-Hui Zhu } 4942ac76fe4e18c3325c8b3bb8f9435fdc7b96c0acaTeng-Hui Zhu } else { 4952ac76fe4e18c3325c8b3bb8f9435fdc7b96c0acaTeng-Hui Zhu // Here before we draw, update the Tile which has updated content. 4962ac76fe4e18c3325c8b3bb8f9435fdc7b96c0acaTeng-Hui Zhu // Inside this function, just do GPU blits from the transfer queue into 4972ac76fe4e18c3325c8b3bb8f9435fdc7b96c0acaTeng-Hui Zhu // the Tiles' texture. 4982ac76fe4e18c3325c8b3bb8f9435fdc7b96c0acaTeng-Hui Zhu transferQueue()->updateDirtyTiles(); 4992ac76fe4e18c3325c8b3bb8f9435fdc7b96c0acaTeng-Hui Zhu // Clean up GL textures for video layer. 5002ac76fe4e18c3325c8b3bb8f9435fdc7b96c0acaTeng-Hui Zhu videoLayerManager()->deleteUnusedTextures(); 5012ac76fe4e18c3325c8b3bb8f9435fdc7b96c0acaTeng-Hui Zhu } 5022ac76fe4e18c3325c8b3bb8f9435fdc7b96c0acaTeng-Hui Zhu m_eglContext = ctx; 5036c4c0302dd154e5090966c57bb4b6b216644fb01Teng-Hui Zhu return; 5042ac76fe4e18c3325c8b3bb8f9435fdc7b96c0acaTeng-Hui Zhu} 5052ac76fe4e18c3325c8b3bb8f9435fdc7b96c0acaTeng-Hui Zhu 506334c36c686871998bf6c4ac958dfe3b3d5a87033Chris Craikvoid TilesManager::removeOperationsForFilter(OperationFilter* filter) 507334c36c686871998bf6c4ac958dfe3b3d5a87033Chris Craik{ 508334c36c686871998bf6c4ac958dfe3b3d5a87033Chris Craik for (int i = 0; i < NUM_TEXTURES_GENERATORS; i++) 509334c36c686871998bf6c4ac958dfe3b3d5a87033Chris Craik m_textureGenerators[i]->removeOperationsForFilter(filter); 510334c36c686871998bf6c4ac958dfe3b3d5a87033Chris Craik delete filter; 511334c36c686871998bf6c4ac958dfe3b3d5a87033Chris Craik} 512334c36c686871998bf6c4ac958dfe3b3d5a87033Chris Craik 513334c36c686871998bf6c4ac958dfe3b3d5a87033Chris Craikbool TilesManager::tryUpdateOperationWithPainter(Tile* tile, TilePainter* painter) 514334c36c686871998bf6c4ac958dfe3b3d5a87033Chris Craik{ 515334c36c686871998bf6c4ac958dfe3b3d5a87033Chris Craik for (int i = 0; i < NUM_TEXTURES_GENERATORS; i++) { 516334c36c686871998bf6c4ac958dfe3b3d5a87033Chris Craik if (m_textureGenerators[i]->tryUpdateOperationWithPainter(tile, painter)) 517334c36c686871998bf6c4ac958dfe3b3d5a87033Chris Craik return true; 518334c36c686871998bf6c4ac958dfe3b3d5a87033Chris Craik } 519334c36c686871998bf6c4ac958dfe3b3d5a87033Chris Craik return false; 520334c36c686871998bf6c4ac958dfe3b3d5a87033Chris Craik} 521334c36c686871998bf6c4ac958dfe3b3d5a87033Chris Craik 522334c36c686871998bf6c4ac958dfe3b3d5a87033Chris Craikvoid TilesManager::scheduleOperation(QueuedOperation* operation) 523334c36c686871998bf6c4ac958dfe3b3d5a87033Chris Craik{ 524334c36c686871998bf6c4ac958dfe3b3d5a87033Chris Craik // TODO: painter awareness, store prefer awareness, store preferred thread into painter 525334c36c686871998bf6c4ac958dfe3b3d5a87033Chris Craik m_scheduleThread = (m_scheduleThread + 1) % NUM_TEXTURES_GENERATORS; 526334c36c686871998bf6c4ac958dfe3b3d5a87033Chris Craik m_textureGenerators[m_scheduleThread]->scheduleOperation(operation); 527334c36c686871998bf6c4ac958dfe3b3d5a87033Chris Craik} 528334c36c686871998bf6c4ac958dfe3b3d5a87033Chris Craik 529e859a34171f2a36877d95197d118d962078f8aa0John Reckint TilesManager::tileWidth() 530a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas Roard{ 531ffc715a2e6382fe9e331557c35fafc426507b8f5Derek Sollenberger return TILE_WIDTH; 532ffc715a2e6382fe9e331557c35fafc426507b8f5Derek Sollenberger} 533ffc715a2e6382fe9e331557c35fafc426507b8f5Derek Sollenberger 534e859a34171f2a36877d95197d118d962078f8aa0John Reckint TilesManager::tileHeight() 535ffc715a2e6382fe9e331557c35fafc426507b8f5Derek Sollenberger{ 536ffc715a2e6382fe9e331557c35fafc426507b8f5Derek Sollenberger return TILE_HEIGHT; 537a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas Roard} 538a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas Roard 539a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas RoardTilesManager* TilesManager::instance() 540a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas Roard{ 541a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas Roard if (!gInstance) { 542a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas Roard gInstance = new TilesManager(); 543d487c56b47c747d3e331ee1892e4c0473363afd2Chris Craik ALOGV("instance(), new gInstance is %x", gInstance); 544a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas Roard } 545a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas Roard return gInstance; 546a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas Roard} 547a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas Roard 548a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas RoardTilesManager* TilesManager::gInstance = 0; 549a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas Roard 550a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas Roard} // namespace WebCore 551a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas Roard 552a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas Roard#endif // USE(ACCELERATED_COMPOSITING) 553