Tile.cpp revision 32ce41e0241790f20e63cafea4d3c1db87423eec
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 26594c6b805969c2673c84d1d1d1a3556ce376ac7aChris Craik#define LOG_TAG "Tile" 27d487c56b47c747d3e331ee1892e4c0473363afd2Chris Craik#define LOG_NDEBUG 1 28d487c56b47c747d3e331ee1892e4c0473363afd2Chris Craik 29a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas Roard#include "config.h" 30594c6b805969c2673c84d1d1d1a3556ce376ac7aChris Craik#include "Tile.h" 31a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas Roard 32a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas Roard#if USE(ACCELERATED_COMPOSITING) 33a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas Roard 34d487c56b47c747d3e331ee1892e4c0473363afd2Chris Craik#include "AndroidLog.h" 35a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas Roard#include "GLUtils.h" 36f85cf343a02e85633e6b68c7f5db3c033b780607Teng-Hui Zhu#include "RasterRenderer.h" 37fca6a67b130c1f97d366460af412ec6e6de14834Derek Sollenberger#include "TextureInfo.h" 38594c6b805969c2673c84d1d1d1a3556ce376ac7aChris Craik#include "TileTexture.h" 39a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas Roard#include "TilesManager.h" 40a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas Roard 41c048426c23be795d3bf870e47429167b4157a2d6Nicolas Roard// If the dirty portion of a tile exceeds this ratio, fully repaint. 42c048426c23be795d3bf870e47429167b4157a2d6Nicolas Roard// Lower values give fewer partial repaints, thus fewer front-to-back 43c048426c23be795d3bf870e47429167b4157a2d6Nicolas Roard// texture copies (cost will vary by device). It's a tradeoff between 44c048426c23be795d3bf870e47429167b4157a2d6Nicolas Roard// the rasterization cost and the FBO texture recopy cost when using 45c048426c23be795d3bf870e47429167b4157a2d6Nicolas Roard// GPU for the transfer queue. 46c048426c23be795d3bf870e47429167b4157a2d6Nicolas Roard#define MAX_INVAL_AREA 0.6 47c048426c23be795d3bf870e47429167b4157a2d6Nicolas Roard 48a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas Roardnamespace WebCore { 49a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas Roard 50594c6b805969c2673c84d1d1d1a3556ce376ac7aChris CraikTile::Tile(bool isLayerTile) 51885e650b12d781be054b31ae6221925a0184dc33Chris Craik : m_x(-1) 52ffc715a2e6382fe9e331557c35fafc426507b8f5Derek Sollenberger , m_y(-1) 538ad3ab0e47f0d5039e89c1873c178f538ec1b0dfChris Craik , m_frontTexture(0) 548ad3ab0e47f0d5039e89c1873c178f538ec1b0dfChris Craik , m_backTexture(0) 55a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas Roard , m_scale(1) 56a1e806ed3b2d9e2727d08cc2a3958fce501f6f33Derek Sollenberger , m_dirty(true) 57417789b7c56928a5fcb610583346d07ffa380900John Reck , m_repaintPending(false) 5862ee9670dd9beeb9a8f21d8737250c081382e2f5Teng-Hui Zhu , m_fullRepaint(true) 593c131605fca8e29a88fdc4923d86bdc3f40adb2bNicolas Roard , m_isLayerTile(isLayerTile) 608ad3ab0e47f0d5039e89c1873c178f538ec1b0dfChris Craik , m_drawCount(0) 61f6a40880028cf495025747229c627f42e25acc66Chris Craik , m_state(Unpainted) 62a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas Roard{ 63a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas Roard#ifdef DEBUG_COUNT 64594c6b805969c2673c84d1d1d1a3556ce376ac7aChris Craik ClassTracker::instance()->increment("Tile"); 65a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas Roard#endif 66c7e578330aece3c556ef205365c24676687223e2Derek Sollenberger m_renderer = BaseRenderer::createRenderer(); 67a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas Roard} 68a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas Roard 69594c6b805969c2673c84d1d1d1a3556ce376ac7aChris CraikTile::~Tile() 70a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas Roard{ 718ad3ab0e47f0d5039e89c1873c178f538ec1b0dfChris Craik if (m_backTexture) 728ad3ab0e47f0d5039e89c1873c178f538ec1b0dfChris Craik m_backTexture->release(this); 738ad3ab0e47f0d5039e89c1873c178f538ec1b0dfChris Craik if (m_frontTexture) 748ad3ab0e47f0d5039e89c1873c178f538ec1b0dfChris Craik m_frontTexture->release(this); 7590455eb70cca2df540942299b35bb3bd8261cb0bDerek Sollenberger 768dfdf8aa25b250ed3b8c0a443cf1cbaf9bd12c5bDerek Sollenberger delete m_renderer; 778dfdf8aa25b250ed3b8c0a443cf1cbaf9bd12c5bDerek Sollenberger 78a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas Roard#ifdef DEBUG_COUNT 79594c6b805969c2673c84d1d1d1a3556ce376ac7aChris Craik ClassTracker::instance()->decrement("Tile"); 80a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas Roard#endif 81a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas Roard} 82a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas Roard 833a7a2aa023d51b1806d4063ab0ea5ef7d488556fNicolas Roard// All the following functions must be called from the main GL thread. 843a7a2aa023d51b1806d4063ab0ea5ef7d488556fNicolas Roard 85594c6b805969c2673c84d1d1d1a3556ce376ac7aChris Craikvoid Tile::setContents(int x, int y, float scale, bool isExpandedPrefetchTile) 86ffc715a2e6382fe9e331557c35fafc426507b8f5Derek Sollenberger{ 87d8be9016b7fda67a91b4ee17b3b2e7ba692ee553Chris Craik // TODO: investigate whether below check/discard is necessary 8892db4f76a7eca8f91084ec2eedde77b161786f23Chris Craik if ((m_x != x) 893c131605fca8e29a88fdc4923d86bdc3f40adb2bNicolas Roard || (m_y != y) 90f6a40880028cf495025747229c627f42e25acc66Chris Craik || (m_scale != scale)) { 91f6a40880028cf495025747229c627f42e25acc66Chris Craik // neither texture is relevant 92f6a40880028cf495025747229c627f42e25acc66Chris Craik discardTextures(); 93f6a40880028cf495025747229c627f42e25acc66Chris Craik } 943c131605fca8e29a88fdc4923d86bdc3f40adb2bNicolas Roard 95f6a40880028cf495025747229c627f42e25acc66Chris Craik android::AutoMutex lock(m_atomicSync); 96ffc715a2e6382fe9e331557c35fafc426507b8f5Derek Sollenberger m_x = x; 97ffc715a2e6382fe9e331557c35fafc426507b8f5Derek Sollenberger m_y = y; 983c131605fca8e29a88fdc4923d86bdc3f40adb2bNicolas Roard m_scale = scale; 998ad3ab0e47f0d5039e89c1873c178f538ec1b0dfChris Craik m_drawCount = TilesManager::instance()->getDrawGLCount(); 100c51715092b8d3be1b51cce8bae61750cbcf342c4Chris Craik if (isExpandedPrefetchTile) 101c51715092b8d3be1b51cce8bae61750cbcf342c4Chris Craik m_drawCount--; // deprioritize expanded painting region 102ffc715a2e6382fe9e331557c35fafc426507b8f5Derek Sollenberger} 103ffc715a2e6382fe9e331557c35fafc426507b8f5Derek Sollenberger 104594c6b805969c2673c84d1d1d1a3556ce376ac7aChris Craikvoid Tile::reserveTexture() 105a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas Roard{ 106594c6b805969c2673c84d1d1d1a3556ce376ac7aChris Craik TileTexture* texture = TilesManager::instance()->getAvailableTexture(this); 107a1e806ed3b2d9e2727d08cc2a3958fce501f6f33Derek Sollenberger 108a1e806ed3b2d9e2727d08cc2a3958fce501f6f33Derek Sollenberger android::AutoMutex lock(m_atomicSync); 1098ad3ab0e47f0d5039e89c1873c178f538ec1b0dfChris Craik if (texture && m_backTexture != texture) { 110d487c56b47c747d3e331ee1892e4c0473363afd2Chris Craik ALOGV("tile %p reserving texture %p, back was %p (front %p)", 111d487c56b47c747d3e331ee1892e4c0473363afd2Chris Craik this, texture, m_backTexture, m_frontTexture); 112f6a40880028cf495025747229c627f42e25acc66Chris Craik m_state = Unpainted; 1138ad3ab0e47f0d5039e89c1873c178f538ec1b0dfChris Craik m_backTexture = texture; 114a1e806ed3b2d9e2727d08cc2a3958fce501f6f33Derek Sollenberger } 1156aa089bded6a1abbf8d61264588e1e3a32be31b3Chris Craik 116f6a40880028cf495025747229c627f42e25acc66Chris Craik if (m_state == UpToDate) { 117d487c56b47c747d3e331ee1892e4c0473363afd2Chris Craik ALOGV("moving tile %p to unpainted, since it reserved while up to date", this); 1186aa089bded6a1abbf8d61264588e1e3a32be31b3Chris Craik m_dirty = true; 119f6a40880028cf495025747229c627f42e25acc66Chris Craik m_state = Unpainted; 120f6a40880028cf495025747229c627f42e25acc66Chris Craik } 121a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas Roard} 122a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas Roard 123594c6b805969c2673c84d1d1d1a3556ce376ac7aChris Craikbool Tile::removeTexture(TileTexture* texture) 124a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas Roard{ 1257b4a179bde698a856bed54a680438a9db3ff0566Chris Craik ALOGV("%p removeTexture %p, back %p front %p", 1267b4a179bde698a856bed54a680438a9db3ff0566Chris Craik this, texture, m_backTexture, m_frontTexture); 1273a7a2aa023d51b1806d4063ab0ea5ef7d488556fNicolas Roard // We update atomically, so paintBitmap() can see the correct value 128a1e806ed3b2d9e2727d08cc2a3958fce501f6f33Derek Sollenberger android::AutoMutex lock(m_atomicSync); 129f6a40880028cf495025747229c627f42e25acc66Chris Craik if (m_frontTexture == texture) { 130f6a40880028cf495025747229c627f42e25acc66Chris Craik if (m_state == UpToDate) { 131d487c56b47c747d3e331ee1892e4c0473363afd2Chris Craik ALOGV("front texture removed, state was UpToDate, now becoming unpainted, bt is %p", m_backTexture); 132f6a40880028cf495025747229c627f42e25acc66Chris Craik m_state = Unpainted; 133f6a40880028cf495025747229c627f42e25acc66Chris Craik } 134f6a40880028cf495025747229c627f42e25acc66Chris Craik 1358ad3ab0e47f0d5039e89c1873c178f538ec1b0dfChris Craik m_frontTexture = 0; 136f6a40880028cf495025747229c627f42e25acc66Chris Craik } 137f6a40880028cf495025747229c627f42e25acc66Chris Craik if (m_backTexture == texture) { 138f6a40880028cf495025747229c627f42e25acc66Chris Craik m_state = Unpainted; 1398ad3ab0e47f0d5039e89c1873c178f538ec1b0dfChris Craik m_backTexture = 0; 140f6a40880028cf495025747229c627f42e25acc66Chris Craik } 1416aa089bded6a1abbf8d61264588e1e3a32be31b3Chris Craik 1426aa089bded6a1abbf8d61264588e1e3a32be31b3Chris Craik // mark dirty regardless of which texture was taken - the back texture may 1436aa089bded6a1abbf8d61264588e1e3a32be31b3Chris Craik // have been ready to swap 1446aa089bded6a1abbf8d61264588e1e3a32be31b3Chris Craik m_dirty = true; 1456aa089bded6a1abbf8d61264588e1e3a32be31b3Chris Craik 14681ec1fafcb2c1bc433ec34b6ae4ea78d1ea7d3a8Nicolas Roard return true; 1473a7a2aa023d51b1806d4063ab0ea5ef7d488556fNicolas Roard} 1483a7a2aa023d51b1806d4063ab0ea5ef7d488556fNicolas Roard 149594c6b805969c2673c84d1d1d1a3556ce376ac7aChris Craikvoid Tile::markAsDirty(const SkRegion& dirtyArea) 150a1e806ed3b2d9e2727d08cc2a3958fce501f6f33Derek Sollenberger{ 151fa807bd31774157959640810e564fbe64338e8e3Nicolas Roard if (dirtyArea.isEmpty()) 152fa807bd31774157959640810e564fbe64338e8e3Nicolas Roard return; 153a1e806ed3b2d9e2727d08cc2a3958fce501f6f33Derek Sollenberger android::AutoMutex lock(m_atomicSync); 15462ee9670dd9beeb9a8f21d8737250c081382e2f5Teng-Hui Zhu m_dirtyArea.op(dirtyArea, SkRegion::kUnion_Op); 15561a908361c8a96eeb70afdb5430e89845edb2bddNicolas Roard 15661a908361c8a96eeb70afdb5430e89845edb2bddNicolas Roard // Check if we actually intersect with the area 15761a908361c8a96eeb70afdb5430e89845edb2bddNicolas Roard bool intersect = false; 15861a908361c8a96eeb70afdb5430e89845edb2bddNicolas Roard SkRegion::Iterator cliperator(dirtyArea); 15961a908361c8a96eeb70afdb5430e89845edb2bddNicolas Roard SkRect realTileRect; 16061a908361c8a96eeb70afdb5430e89845edb2bddNicolas Roard SkRect dirtyRect; 16161a908361c8a96eeb70afdb5430e89845edb2bddNicolas Roard while (!cliperator.done()) { 16261a908361c8a96eeb70afdb5430e89845edb2bddNicolas Roard dirtyRect.set(cliperator.rect()); 163c51715092b8d3be1b51cce8bae61750cbcf342c4Chris Craik if (intersectWithRect(m_x, m_y, TilesManager::tileWidth(), TilesManager::tileHeight(), 16461a908361c8a96eeb70afdb5430e89845edb2bddNicolas Roard m_scale, dirtyRect, realTileRect)) { 16561a908361c8a96eeb70afdb5430e89845edb2bddNicolas Roard intersect = true; 16661a908361c8a96eeb70afdb5430e89845edb2bddNicolas Roard break; 16761a908361c8a96eeb70afdb5430e89845edb2bddNicolas Roard } 16861a908361c8a96eeb70afdb5430e89845edb2bddNicolas Roard cliperator.next(); 16961a908361c8a96eeb70afdb5430e89845edb2bddNicolas Roard } 17008c253c5d2dad921120c3e1ab7bc6781064ca31bNicolas Roard 17161a908361c8a96eeb70afdb5430e89845edb2bddNicolas Roard if (!intersect) 17261a908361c8a96eeb70afdb5430e89845edb2bddNicolas Roard return; 17361a908361c8a96eeb70afdb5430e89845edb2bddNicolas Roard 17467e4aa15702646d5ff50e9524f4e63eb9ed20122Nicolas Roard m_dirty = true; 175f6a40880028cf495025747229c627f42e25acc66Chris Craik if (m_state == UpToDate) { 176f6a40880028cf495025747229c627f42e25acc66Chris Craik // We only mark a tile as unpainted in 'markAsDirty' if its status is 177f6a40880028cf495025747229c627f42e25acc66Chris Craik // UpToDate: marking dirty means we need to repaint, but don't stop the 178f6a40880028cf495025747229c627f42e25acc66Chris Craik // current paint 179f6a40880028cf495025747229c627f42e25acc66Chris Craik m_state = Unpainted; 180f6a40880028cf495025747229c627f42e25acc66Chris Craik } else if (m_state != Unpainted) { 181f6a40880028cf495025747229c627f42e25acc66Chris Craik // TODO: fix it so that they can paint while deferring the markAsDirty 182f6a40880028cf495025747229c627f42e25acc66Chris Craik // call (or block updates) 1837b4a179bde698a856bed54a680438a9db3ff0566Chris Craik ALOGV("Warning: tried to mark tile %p at %d, %d islayertile %d as dirty, state %d", 1847b4a179bde698a856bed54a680438a9db3ff0566Chris Craik this, m_x, m_y, isLayerTile(), m_state); 185458b4b11924c3bcc70dcdd3d69f64a855870e72dChris Craik 186458b4b11924c3bcc70dcdd3d69f64a855870e72dChris Craik // prefetch tiles can be marked dirty while in the process of painting, 187458b4b11924c3bcc70dcdd3d69f64a855870e72dChris Craik // due to not using an update lock. force them to fail validate step. 188458b4b11924c3bcc70dcdd3d69f64a855870e72dChris Craik m_state = Unpainted; 189f6a40880028cf495025747229c627f42e25acc66Chris Craik } 190a1e806ed3b2d9e2727d08cc2a3958fce501f6f33Derek Sollenberger} 191a1e806ed3b2d9e2727d08cc2a3958fce501f6f33Derek Sollenberger 192594c6b805969c2673c84d1d1d1a3556ce376ac7aChris Craikbool Tile::isDirty() 193a1e806ed3b2d9e2727d08cc2a3958fce501f6f33Derek Sollenberger{ 194a1e806ed3b2d9e2727d08cc2a3958fce501f6f33Derek Sollenberger android::AutoMutex lock(m_atomicSync); 195a1e806ed3b2d9e2727d08cc2a3958fce501f6f33Derek Sollenberger return m_dirty; 196a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas Roard} 197a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas Roard 198594c6b805969c2673c84d1d1d1a3556ce376ac7aChris Craikbool Tile::isRepaintPending() 199417789b7c56928a5fcb610583346d07ffa380900John Reck{ 200417789b7c56928a5fcb610583346d07ffa380900John Reck android::AutoMutex lock(m_atomicSync); 201417789b7c56928a5fcb610583346d07ffa380900John Reck return m_repaintPending; 202417789b7c56928a5fcb610583346d07ffa380900John Reck} 203417789b7c56928a5fcb610583346d07ffa380900John Reck 204594c6b805969c2673c84d1d1d1a3556ce376ac7aChris Craikvoid Tile::setRepaintPending(bool pending) 205417789b7c56928a5fcb610583346d07ffa380900John Reck{ 206417789b7c56928a5fcb610583346d07ffa380900John Reck android::AutoMutex lock(m_atomicSync); 207417789b7c56928a5fcb610583346d07ffa380900John Reck m_repaintPending = pending; 208417789b7c56928a5fcb610583346d07ffa380900John Reck} 209417789b7c56928a5fcb610583346d07ffa380900John Reck 210594c6b805969c2673c84d1d1d1a3556ce376ac7aChris Craikbool Tile::drawGL(float opacity, const SkRect& rect, float scale, 211a31d28d03260660f592ad6914f5375b47e823aa5Teng-Hui Zhu const TransformationMatrix* transform, 21232ce41e0241790f20e63cafea4d3c1db87423eecChris Craik bool forceBlending, bool usePointSampling, 21332ce41e0241790f20e63cafea4d3c1db87423eecChris Craik const FloatPoint& fillPortion) 214a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas Roard{ 2151deed5ff76dad5d0783c0e07639338f1d6b08a67Nicolas Roard if (m_x < 0 || m_y < 0 || m_scale != scale) 216afe34397d6d4655c908f0995e760772980722da3Teng-Hui Zhu return false; 21767e4aa15702646d5ff50e9524f4e63eb9ed20122Nicolas Roard 2188ad3ab0e47f0d5039e89c1873c178f538ec1b0dfChris Craik // No need to mutex protect reads of m_backTexture as it is only written to by 219a1e806ed3b2d9e2727d08cc2a3958fce501f6f33Derek Sollenberger // the consumer thread. 2208ad3ab0e47f0d5039e89c1873c178f538ec1b0dfChris Craik if (!m_frontTexture) 221afe34397d6d4655c908f0995e760772980722da3Teng-Hui Zhu return false; 222a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas Roard 22332ce41e0241790f20e63cafea4d3c1db87423eecChris Craik if (fillPortion.x() < 1.0f || fillPortion.y() < 1.0f) 22432ce41e0241790f20e63cafea4d3c1db87423eecChris Craik ALOGV("drawing tile %p (%d, %d with fill portions %f %f", 22532ce41e0241790f20e63cafea4d3c1db87423eecChris Craik this, m_x, m_y, fillPortion.x(), fillPortion.y()); 22632ce41e0241790f20e63cafea4d3c1db87423eecChris Craik 2273efc67e0caf0b63fe0350d6896d2cbc08661f5d7Teng-Hui Zhu m_frontTexture->drawGL(isLayerTile(), rect, opacity, transform, 22832ce41e0241790f20e63cafea4d3c1db87423eecChris Craik forceBlending, usePointSampling, fillPortion); 229afe34397d6d4655c908f0995e760772980722da3Teng-Hui Zhu return true; 230a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas Roard} 231a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas Roard 232594c6b805969c2673c84d1d1d1a3556ce376ac7aChris Craikbool Tile::isTileReady() 233a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas Roard{ 2348ad3ab0e47f0d5039e89c1873c178f538ec1b0dfChris Craik // Return true if the tile's most recently drawn texture is up to date 2358ad3ab0e47f0d5039e89c1873c178f538ec1b0dfChris Craik android::AutoMutex lock(m_atomicSync); 236594c6b805969c2673c84d1d1d1a3556ce376ac7aChris Craik TileTexture * texture = (m_state == ReadyToSwap) ? m_backTexture : m_frontTexture; 2378ad3ab0e47f0d5039e89c1873c178f538ec1b0dfChris Craik 2388ad3ab0e47f0d5039e89c1873c178f538ec1b0dfChris Craik if (!texture) 239a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas Roard return false; 2408ad3ab0e47f0d5039e89c1873c178f538ec1b0dfChris Craik 2418ad3ab0e47f0d5039e89c1873c178f538ec1b0dfChris Craik if (texture->owner() != this) 242a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas Roard return false; 243a1e806ed3b2d9e2727d08cc2a3958fce501f6f33Derek Sollenberger 24467e4aa15702646d5ff50e9524f4e63eb9ed20122Nicolas Roard if (m_dirty) 24567e4aa15702646d5ff50e9524f4e63eb9ed20122Nicolas Roard return false; 24667e4aa15702646d5ff50e9524f4e63eb9ed20122Nicolas Roard 247f6a40880028cf495025747229c627f42e25acc66Chris Craik if (m_state != ReadyToSwap && m_state != UpToDate) 248f6a40880028cf495025747229c627f42e25acc66Chris Craik return false; 249f6a40880028cf495025747229c627f42e25acc66Chris Craik 250f8f42bbda64a56cfd5ab48a274020d4efc9a5594Chris Craik return true; 251a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas Roard} 252a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas Roard 253594c6b805969c2673c84d1d1d1a3556ce376ac7aChris Craikbool Tile::intersectWithRect(int x, int y, int tileWidth, int tileHeight, 254594c6b805969c2673c84d1d1d1a3556ce376ac7aChris Craik float scale, const SkRect& dirtyRect, 255594c6b805969c2673c84d1d1d1a3556ce376ac7aChris Craik SkRect& realTileRect) 256fa807bd31774157959640810e564fbe64338e8e3Nicolas Roard{ 257fa807bd31774157959640810e564fbe64338e8e3Nicolas Roard // compute the rect to corresponds to pixels 258fa807bd31774157959640810e564fbe64338e8e3Nicolas Roard realTileRect.fLeft = x * tileWidth; 259fa807bd31774157959640810e564fbe64338e8e3Nicolas Roard realTileRect.fTop = y * tileHeight; 260fa807bd31774157959640810e564fbe64338e8e3Nicolas Roard realTileRect.fRight = realTileRect.fLeft + tileWidth; 261fa807bd31774157959640810e564fbe64338e8e3Nicolas Roard realTileRect.fBottom = realTileRect.fTop + tileHeight; 262fa807bd31774157959640810e564fbe64338e8e3Nicolas Roard 263fa807bd31774157959640810e564fbe64338e8e3Nicolas Roard // scale the dirtyRect for intersect computation. 264fa807bd31774157959640810e564fbe64338e8e3Nicolas Roard SkRect realDirtyRect = SkRect::MakeWH(dirtyRect.width() * scale, 265fa807bd31774157959640810e564fbe64338e8e3Nicolas Roard dirtyRect.height() * scale); 266fa807bd31774157959640810e564fbe64338e8e3Nicolas Roard realDirtyRect.offset(dirtyRect.fLeft * scale, dirtyRect.fTop * scale); 267fa807bd31774157959640810e564fbe64338e8e3Nicolas Roard 268fa807bd31774157959640810e564fbe64338e8e3Nicolas Roard if (!realTileRect.intersect(realDirtyRect)) 269fa807bd31774157959640810e564fbe64338e8e3Nicolas Roard return false; 270fa807bd31774157959640810e564fbe64338e8e3Nicolas Roard return true; 271fa807bd31774157959640810e564fbe64338e8e3Nicolas Roard} 272fa807bd31774157959640810e564fbe64338e8e3Nicolas Roard 273594c6b805969c2673c84d1d1d1a3556ce376ac7aChris Craikbool Tile::isTileVisible(const IntRect& viewTileBounds) 274e48d27773894f36d85e5c2e2052ab90d502e1c72Chris Craik{ 275e48d27773894f36d85e5c2e2052ab90d502e1c72Chris Craik return (m_x >= viewTileBounds.x() 276e48d27773894f36d85e5c2e2052ab90d502e1c72Chris Craik && m_x < viewTileBounds.x() + viewTileBounds.width() 277e48d27773894f36d85e5c2e2052ab90d502e1c72Chris Craik && m_y >= viewTileBounds.y() 278e48d27773894f36d85e5c2e2052ab90d502e1c72Chris Craik && m_y < viewTileBounds.y() + viewTileBounds.height()); 279e48d27773894f36d85e5c2e2052ab90d502e1c72Chris Craik} 280e48d27773894f36d85e5c2e2052ab90d502e1c72Chris Craik 2813a7a2aa023d51b1806d4063ab0ea5ef7d488556fNicolas Roard// This is called from the texture generation thread 282594c6b805969c2673c84d1d1d1a3556ce376ac7aChris Craikvoid Tile::paintBitmap(TilePainter* painter) 283a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas Roard{ 284a1e806ed3b2d9e2727d08cc2a3958fce501f6f33Derek Sollenberger // We acquire the values below atomically. This ensures that we are reading 285a1e806ed3b2d9e2727d08cc2a3958fce501f6f33Derek Sollenberger // values correctly across cores. Further, once we have these values they 286a1e806ed3b2d9e2727d08cc2a3958fce501f6f33Derek Sollenberger // can be updated by other threads without consequence. 287a1e806ed3b2d9e2727d08cc2a3958fce501f6f33Derek Sollenberger m_atomicSync.lock(); 288a1e806ed3b2d9e2727d08cc2a3958fce501f6f33Derek Sollenberger bool dirty = m_dirty; 289594c6b805969c2673c84d1d1d1a3556ce376ac7aChris Craik TileTexture* texture = m_backTexture; 29062ee9670dd9beeb9a8f21d8737250c081382e2f5Teng-Hui Zhu SkRegion dirtyArea = m_dirtyArea; 2913a7a2aa023d51b1806d4063ab0ea5ef7d488556fNicolas Roard float scale = m_scale; 292be61abb47b98988ca94bd839a1e17c3267365dc9Nicolas Roard const int x = m_x; 293be61abb47b98988ca94bd839a1e17c3267365dc9Nicolas Roard const int y = m_y; 294cf1ae53e7b2853d1148ecd784379f12dffda9d43Nicolas Roard 2953c131605fca8e29a88fdc4923d86bdc3f40adb2bNicolas Roard if (!dirty || !texture) { 2963c131605fca8e29a88fdc4923d86bdc3f40adb2bNicolas Roard m_atomicSync.unlock(); 29775394f5ee0aac2337cdff1597b4e686e22c52833Nicolas Roard return; 2983c131605fca8e29a88fdc4923d86bdc3f40adb2bNicolas Roard } 299f6a40880028cf495025747229c627f42e25acc66Chris Craik if (m_state != Unpainted) { 300d487c56b47c747d3e331ee1892e4c0473363afd2Chris Craik ALOGV("Warning: started painting tile %p, but was at state %d, ft %p bt %p", 301f6a40880028cf495025747229c627f42e25acc66Chris Craik this, m_state, m_frontTexture, m_backTexture); 302f6a40880028cf495025747229c627f42e25acc66Chris Craik } 303f6a40880028cf495025747229c627f42e25acc66Chris Craik m_state = PaintingStarted; 30462ee9670dd9beeb9a8f21d8737250c081382e2f5Teng-Hui Zhu TextureInfo* textureInfo = texture->getTextureInfo(); 3053c131605fca8e29a88fdc4923d86bdc3f40adb2bNicolas Roard m_atomicSync.unlock(); 306a52793c453c1512d0a18d4ae3108a975f998ae45Derek Sollenberger 307a1e806ed3b2d9e2727d08cc2a3958fce501f6f33Derek Sollenberger // at this point we can safely check the ownership (if the texture got 308594c6b805969c2673c84d1d1d1a3556ce376ac7aChris Craik // transferred to another Tile under us) 3098ad3ab0e47f0d5039e89c1873c178f538ec1b0dfChris Craik if (texture->owner() != this) { 31075394f5ee0aac2337cdff1597b4e686e22c52833Nicolas Roard return; 311a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas Roard } 312a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas Roard 313c7e578330aece3c556ef205365c24676687223e2Derek Sollenberger // swap out the renderer if necessary 314c7e578330aece3c556ef205365c24676687223e2Derek Sollenberger BaseRenderer::swapRendererIfNeeded(m_renderer); 315232d0b3572d13d9b4fb1211d9d56252a1ede3ed6Derek Sollenberger // setup the common renderInfo fields; 316232d0b3572d13d9b4fb1211d9d56252a1ede3ed6Derek Sollenberger TileRenderInfo renderInfo; 317232d0b3572d13d9b4fb1211d9d56252a1ede3ed6Derek Sollenberger renderInfo.x = x; 318232d0b3572d13d9b4fb1211d9d56252a1ede3ed6Derek Sollenberger renderInfo.y = y; 319232d0b3572d13d9b4fb1211d9d56252a1ede3ed6Derek Sollenberger renderInfo.scale = scale; 320232d0b3572d13d9b4fb1211d9d56252a1ede3ed6Derek Sollenberger renderInfo.tileSize = texture->getSize(); 3213c131605fca8e29a88fdc4923d86bdc3f40adb2bNicolas Roard renderInfo.tilePainter = painter; 3223c131605fca8e29a88fdc4923d86bdc3f40adb2bNicolas Roard renderInfo.baseTile = this; 323232d0b3572d13d9b4fb1211d9d56252a1ede3ed6Derek Sollenberger renderInfo.textureInfo = textureInfo; 324232d0b3572d13d9b4fb1211d9d56252a1ede3ed6Derek Sollenberger 325232d0b3572d13d9b4fb1211d9d56252a1ede3ed6Derek Sollenberger const float tileWidth = renderInfo.tileSize.width(); 326232d0b3572d13d9b4fb1211d9d56252a1ede3ed6Derek Sollenberger const float tileHeight = renderInfo.tileSize.height(); 327232d0b3572d13d9b4fb1211d9d56252a1ede3ed6Derek Sollenberger 32867e4aa15702646d5ff50e9524f4e63eb9ed20122Nicolas Roard SkRegion::Iterator cliperator(dirtyArea); 32967e4aa15702646d5ff50e9524f4e63eb9ed20122Nicolas Roard 33067e4aa15702646d5ff50e9524f4e63eb9ed20122Nicolas Roard bool fullRepaint = false; 331f85cf343a02e85633e6b68c7f5db3c033b780607Teng-Hui Zhu 33262ee9670dd9beeb9a8f21d8737250c081382e2f5Teng-Hui Zhu if (m_fullRepaint 333f85cf343a02e85633e6b68c7f5db3c033b780607Teng-Hui Zhu || textureInfo->m_width != tileWidth 334fa807bd31774157959640810e564fbe64338e8e3Nicolas Roard || textureInfo->m_height != tileHeight) { 33567e4aa15702646d5ff50e9524f4e63eb9ed20122Nicolas Roard fullRepaint = true; 336fca6a67b130c1f97d366460af412ec6e6de14834Derek Sollenberger } 33767e4aa15702646d5ff50e9524f4e63eb9ed20122Nicolas Roard 338c048426c23be795d3bf870e47429167b4157a2d6Nicolas Roard // For now, only do full repaint 33962ee9670dd9beeb9a8f21d8737250c081382e2f5Teng-Hui Zhu fullRepaint = true; 3405d77d7f575389ee1f20a394c635928c2e75667c7Nicolas Roard 341c048426c23be795d3bf870e47429167b4157a2d6Nicolas Roard if (!fullRepaint) { 342c048426c23be795d3bf870e47429167b4157a2d6Nicolas Roard // compute the partial inval area 343c048426c23be795d3bf870e47429167b4157a2d6Nicolas Roard SkIRect totalRect; 344c048426c23be795d3bf870e47429167b4157a2d6Nicolas Roard totalRect.set(0, 0, 0, 0); 345c048426c23be795d3bf870e47429167b4157a2d6Nicolas Roard float tileSurface = tileWidth * tileHeight; 346c048426c23be795d3bf870e47429167b4157a2d6Nicolas Roard float tileSurfaceCap = MAX_INVAL_AREA * tileSurface; 347c048426c23be795d3bf870e47429167b4157a2d6Nicolas Roard 348c048426c23be795d3bf870e47429167b4157a2d6Nicolas Roard // We join all the invals in the same tile for now 349c048426c23be795d3bf870e47429167b4157a2d6Nicolas Roard while (!fullRepaint && !cliperator.done()) { 350c048426c23be795d3bf870e47429167b4157a2d6Nicolas Roard SkRect realTileRect; 351c048426c23be795d3bf870e47429167b4157a2d6Nicolas Roard SkRect dirtyRect; 352c048426c23be795d3bf870e47429167b4157a2d6Nicolas Roard dirtyRect.set(cliperator.rect()); 353c048426c23be795d3bf870e47429167b4157a2d6Nicolas Roard bool intersect = intersectWithRect(x, y, tileWidth, tileHeight, 354c048426c23be795d3bf870e47429167b4157a2d6Nicolas Roard scale, dirtyRect, realTileRect); 355c048426c23be795d3bf870e47429167b4157a2d6Nicolas Roard if (intersect) { 356c048426c23be795d3bf870e47429167b4157a2d6Nicolas Roard // initialize finalRealRect to the rounded values of realTileRect 357c048426c23be795d3bf870e47429167b4157a2d6Nicolas Roard SkIRect finalRealRect; 358c048426c23be795d3bf870e47429167b4157a2d6Nicolas Roard realTileRect.roundOut(&finalRealRect); 359c048426c23be795d3bf870e47429167b4157a2d6Nicolas Roard 360c048426c23be795d3bf870e47429167b4157a2d6Nicolas Roard // stash the int values of the current width and height 361c048426c23be795d3bf870e47429167b4157a2d6Nicolas Roard const int iWidth = finalRealRect.width(); 362c048426c23be795d3bf870e47429167b4157a2d6Nicolas Roard const int iHeight = finalRealRect.height(); 363c048426c23be795d3bf870e47429167b4157a2d6Nicolas Roard 364c048426c23be795d3bf870e47429167b4157a2d6Nicolas Roard if (iWidth == tileWidth || iHeight == tileHeight) { 365c048426c23be795d3bf870e47429167b4157a2d6Nicolas Roard fullRepaint = true; 366c048426c23be795d3bf870e47429167b4157a2d6Nicolas Roard break; 367c048426c23be795d3bf870e47429167b4157a2d6Nicolas Roard } 368c048426c23be795d3bf870e47429167b4157a2d6Nicolas Roard 369c048426c23be795d3bf870e47429167b4157a2d6Nicolas Roard // translate the rect into tile space coordinates 370c048426c23be795d3bf870e47429167b4157a2d6Nicolas Roard finalRealRect.fLeft = finalRealRect.fLeft % static_cast<int>(tileWidth); 371c048426c23be795d3bf870e47429167b4157a2d6Nicolas Roard finalRealRect.fTop = finalRealRect.fTop % static_cast<int>(tileHeight); 372c048426c23be795d3bf870e47429167b4157a2d6Nicolas Roard finalRealRect.fRight = finalRealRect.fLeft + iWidth; 373c048426c23be795d3bf870e47429167b4157a2d6Nicolas Roard finalRealRect.fBottom = finalRealRect.fTop + iHeight; 374c048426c23be795d3bf870e47429167b4157a2d6Nicolas Roard totalRect.join(finalRealRect); 375c048426c23be795d3bf870e47429167b4157a2d6Nicolas Roard float repaintSurface = totalRect.width() * totalRect.height(); 376c048426c23be795d3bf870e47429167b4157a2d6Nicolas Roard 377c048426c23be795d3bf870e47429167b4157a2d6Nicolas Roard if (repaintSurface > tileSurfaceCap) { 378c048426c23be795d3bf870e47429167b4157a2d6Nicolas Roard fullRepaint = true; 379c048426c23be795d3bf870e47429167b4157a2d6Nicolas Roard break; 380c048426c23be795d3bf870e47429167b4157a2d6Nicolas Roard } 381fca6a67b130c1f97d366460af412ec6e6de14834Derek Sollenberger } 382fca6a67b130c1f97d366460af412ec6e6de14834Derek Sollenberger 383c048426c23be795d3bf870e47429167b4157a2d6Nicolas Roard cliperator.next(); 384c048426c23be795d3bf870e47429167b4157a2d6Nicolas Roard } 38567e4aa15702646d5ff50e9524f4e63eb9ed20122Nicolas Roard 386c048426c23be795d3bf870e47429167b4157a2d6Nicolas Roard if (!fullRepaint) { 387c048426c23be795d3bf870e47429167b4157a2d6Nicolas Roard renderInfo.invalRect = &totalRect; 388f7ad77dc2a981834d664fd24022c3dfade69c8aaChris Craik m_renderer->renderTiledContent(renderInfo); 38967e4aa15702646d5ff50e9524f4e63eb9ed20122Nicolas Roard } 39067e4aa15702646d5ff50e9524f4e63eb9ed20122Nicolas Roard } 391fca6a67b130c1f97d366460af412ec6e6de14834Derek Sollenberger 392fa807bd31774157959640810e564fbe64338e8e3Nicolas Roard // Do a full repaint if needed 393fca6a67b130c1f97d366460af412ec6e6de14834Derek Sollenberger if (fullRepaint) { 394c048426c23be795d3bf870e47429167b4157a2d6Nicolas Roard renderInfo.invalRect = 0; 395f7ad77dc2a981834d664fd24022c3dfade69c8aaChris Craik m_renderer->renderTiledContent(renderInfo); 396fca6a67b130c1f97d366460af412ec6e6de14834Derek Sollenberger } 397fca6a67b130c1f97d366460af412ec6e6de14834Derek Sollenberger 39867e4aa15702646d5ff50e9524f4e63eb9ed20122Nicolas Roard m_atomicSync.lock(); 3997c554a61cb935660cdc86905d040c781b490150fTeng-Hui Zhu 4008ad3ab0e47f0d5039e89c1873c178f538ec1b0dfChris Craik if (texture == m_backTexture) { 4015ba4a087b9212ca9ae083f015637f417199d85ccJohn Reck // set the fullrepaint flags 40262ee9670dd9beeb9a8f21d8737250c081382e2f5Teng-Hui Zhu m_fullRepaint = false; 40367e4aa15702646d5ff50e9524f4e63eb9ed20122Nicolas Roard 4045ba4a087b9212ca9ae083f015637f417199d85ccJohn Reck // The various checks to see if we are still dirty... 40567e4aa15702646d5ff50e9524f4e63eb9ed20122Nicolas Roard 4065ba4a087b9212ca9ae083f015637f417199d85ccJohn Reck m_dirty = false; 40767e4aa15702646d5ff50e9524f4e63eb9ed20122Nicolas Roard 4085ba4a087b9212ca9ae083f015637f417199d85ccJohn Reck if (m_scale != scale) 4095ba4a087b9212ca9ae083f015637f417199d85ccJohn Reck m_dirty = true; 41067e4aa15702646d5ff50e9524f4e63eb9ed20122Nicolas Roard 411fca6a67b130c1f97d366460af412ec6e6de14834Derek Sollenberger if (fullRepaint) 41262ee9670dd9beeb9a8f21d8737250c081382e2f5Teng-Hui Zhu m_dirtyArea.setEmpty(); 413fca6a67b130c1f97d366460af412ec6e6de14834Derek Sollenberger else 41462ee9670dd9beeb9a8f21d8737250c081382e2f5Teng-Hui Zhu m_dirtyArea.op(dirtyArea, SkRegion::kDifference_Op); 41567e4aa15702646d5ff50e9524f4e63eb9ed20122Nicolas Roard 41662ee9670dd9beeb9a8f21d8737250c081382e2f5Teng-Hui Zhu if (!m_dirtyArea.isEmpty()) 4175ba4a087b9212ca9ae083f015637f417199d85ccJohn Reck m_dirty = true; 418c15781f45f0d19a925be7fd73bd10c318562db70Nicolas Roard 419d487c56b47c747d3e331ee1892e4c0473363afd2Chris Craik ALOGV("painted tile %p (%d, %d), texture %p, dirty=%d", this, x, y, texture, m_dirty); 420e733717c7b60d2ccfee9c47af4659ffb8e70dd73Chris Craik 421f6a40880028cf495025747229c627f42e25acc66Chris Craik validatePaint(); 422f6a40880028cf495025747229c627f42e25acc66Chris Craik } else { 423d487c56b47c747d3e331ee1892e4c0473363afd2Chris Craik ALOGV("tile %p no longer owns texture %p, m_state %d. ft %p bt %p", 424d487c56b47c747d3e331ee1892e4c0473363afd2Chris Craik this, texture, m_state, m_frontTexture, m_backTexture); 4255ba4a087b9212ca9ae083f015637f417199d85ccJohn Reck } 42667e4aa15702646d5ff50e9524f4e63eb9ed20122Nicolas Roard 42767e4aa15702646d5ff50e9524f4e63eb9ed20122Nicolas Roard m_atomicSync.unlock(); 42867e4aa15702646d5ff50e9524f4e63eb9ed20122Nicolas Roard} 42967e4aa15702646d5ff50e9524f4e63eb9ed20122Nicolas Roard 430594c6b805969c2673c84d1d1d1a3556ce376ac7aChris Craikvoid Tile::discardTextures() { 4318ad3ab0e47f0d5039e89c1873c178f538ec1b0dfChris Craik android::AutoMutex lock(m_atomicSync); 432d487c56b47c747d3e331ee1892e4c0473363afd2Chris Craik ALOGV("%p discarding bt %p, ft %p", 433d487c56b47c747d3e331ee1892e4c0473363afd2Chris Craik this, m_backTexture, m_frontTexture); 4348ad3ab0e47f0d5039e89c1873c178f538ec1b0dfChris Craik if (m_frontTexture) { 4358ad3ab0e47f0d5039e89c1873c178f538ec1b0dfChris Craik m_frontTexture->release(this); 4368ad3ab0e47f0d5039e89c1873c178f538ec1b0dfChris Craik m_frontTexture = 0; 4378ad3ab0e47f0d5039e89c1873c178f538ec1b0dfChris Craik } 4388ad3ab0e47f0d5039e89c1873c178f538ec1b0dfChris Craik if (m_backTexture) { 4398ad3ab0e47f0d5039e89c1873c178f538ec1b0dfChris Craik m_backTexture->release(this); 4408ad3ab0e47f0d5039e89c1873c178f538ec1b0dfChris Craik m_backTexture = 0; 4418ad3ab0e47f0d5039e89c1873c178f538ec1b0dfChris Craik } 44262ee9670dd9beeb9a8f21d8737250c081382e2f5Teng-Hui Zhu m_dirtyArea.setEmpty(); 44362ee9670dd9beeb9a8f21d8737250c081382e2f5Teng-Hui Zhu m_fullRepaint = true; 44462ee9670dd9beeb9a8f21d8737250c081382e2f5Teng-Hui Zhu 4458ad3ab0e47f0d5039e89c1873c178f538ec1b0dfChris Craik m_dirty = true; 446f6a40880028cf495025747229c627f42e25acc66Chris Craik m_state = Unpainted; 4478ad3ab0e47f0d5039e89c1873c178f538ec1b0dfChris Craik} 4488ad3ab0e47f0d5039e89c1873c178f538ec1b0dfChris Craik 449594c6b805969c2673c84d1d1d1a3556ce376ac7aChris Craikvoid Tile::discardBackTexture() { 4503a819aac70dd26f675644f6a35b13be5fb3de2f1Chris Craik android::AutoMutex lock(m_atomicSync); 4513a819aac70dd26f675644f6a35b13be5fb3de2f1Chris Craik if (m_backTexture) { 4523a819aac70dd26f675644f6a35b13be5fb3de2f1Chris Craik m_backTexture->release(this); 4533a819aac70dd26f675644f6a35b13be5fb3de2f1Chris Craik m_backTexture = 0; 4543a819aac70dd26f675644f6a35b13be5fb3de2f1Chris Craik } 4553ef9d5cc655b8274860b8d15441201d3e621baf5Chris Craik m_state = Unpainted; 4563ef9d5cc655b8274860b8d15441201d3e621baf5Chris Craik m_dirty = true; 4573a819aac70dd26f675644f6a35b13be5fb3de2f1Chris Craik} 4583a819aac70dd26f675644f6a35b13be5fb3de2f1Chris Craik 459594c6b805969c2673c84d1d1d1a3556ce376ac7aChris Craikbool Tile::swapTexturesIfNeeded() { 4608ad3ab0e47f0d5039e89c1873c178f538ec1b0dfChris Craik android::AutoMutex lock(m_atomicSync); 461f6a40880028cf495025747229c627f42e25acc66Chris Craik if (m_state == ReadyToSwap) { 4628ad3ab0e47f0d5039e89c1873c178f538ec1b0dfChris Craik // discard old texture and swap the new one in its place 4638ad3ab0e47f0d5039e89c1873c178f538ec1b0dfChris Craik if (m_frontTexture) 4648ad3ab0e47f0d5039e89c1873c178f538ec1b0dfChris Craik m_frontTexture->release(this); 4658ad3ab0e47f0d5039e89c1873c178f538ec1b0dfChris Craik 4668ad3ab0e47f0d5039e89c1873c178f538ec1b0dfChris Craik m_frontTexture = m_backTexture; 4678ad3ab0e47f0d5039e89c1873c178f538ec1b0dfChris Craik m_backTexture = 0; 468f6a40880028cf495025747229c627f42e25acc66Chris Craik m_state = UpToDate; 469d487c56b47c747d3e331ee1892e4c0473363afd2Chris Craik ALOGV("display texture for %p at %d, %d front is now %p, back is %p", 470d487c56b47c747d3e331ee1892e4c0473363afd2Chris Craik this, m_x, m_y, m_frontTexture, m_backTexture); 471f6a40880028cf495025747229c627f42e25acc66Chris Craik 4728ad3ab0e47f0d5039e89c1873c178f538ec1b0dfChris Craik return true; 4738ad3ab0e47f0d5039e89c1873c178f538ec1b0dfChris Craik } 4748ad3ab0e47f0d5039e89c1873c178f538ec1b0dfChris Craik return false; 4758ad3ab0e47f0d5039e89c1873c178f538ec1b0dfChris Craik} 4768ad3ab0e47f0d5039e89c1873c178f538ec1b0dfChris Craik 477594c6b805969c2673c84d1d1d1a3556ce376ac7aChris Craikvoid Tile::backTextureTransfer() { 478f6a40880028cf495025747229c627f42e25acc66Chris Craik android::AutoMutex lock(m_atomicSync); 479f6a40880028cf495025747229c627f42e25acc66Chris Craik if (m_state == PaintingStarted) 480f6a40880028cf495025747229c627f42e25acc66Chris Craik m_state = TransferredUnvalidated; 481f6a40880028cf495025747229c627f42e25acc66Chris Craik else if (m_state == ValidatedUntransferred) 482f6a40880028cf495025747229c627f42e25acc66Chris Craik m_state = ReadyToSwap; 483f6a40880028cf495025747229c627f42e25acc66Chris Craik else { 484f6a40880028cf495025747229c627f42e25acc66Chris Craik // shouldn't have transferred a tile in any other state, log 485d487c56b47c747d3e331ee1892e4c0473363afd2Chris Craik ALOGV("Note: transferred tile %p at %d %d, state wasn't paintingstarted or validated: %d", 486d487c56b47c747d3e331ee1892e4c0473363afd2Chris Craik this, m_x, m_y, m_state); 487f6a40880028cf495025747229c627f42e25acc66Chris Craik } 488f6a40880028cf495025747229c627f42e25acc66Chris Craik} 489f6a40880028cf495025747229c627f42e25acc66Chris Craik 490594c6b805969c2673c84d1d1d1a3556ce376ac7aChris Craikvoid Tile::backTextureTransferFail() { 491530c83c6351e05a6939ad0b5bc291da073e77b5bChris Craik // transfer failed for some reason, mark dirty so it will (repaint and) be 492530c83c6351e05a6939ad0b5bc291da073e77b5bChris Craik // retransferred. 493530c83c6351e05a6939ad0b5bc291da073e77b5bChris Craik android::AutoMutex lock(m_atomicSync); 494530c83c6351e05a6939ad0b5bc291da073e77b5bChris Craik m_state = Unpainted; 4953ef9d5cc655b8274860b8d15441201d3e621baf5Chris Craik m_dirty = true; 496530c83c6351e05a6939ad0b5bc291da073e77b5bChris Craik // whether validatePaint is called before or after, it won't do anything 497530c83c6351e05a6939ad0b5bc291da073e77b5bChris Craik} 498530c83c6351e05a6939ad0b5bc291da073e77b5bChris Craik 499594c6b805969c2673c84d1d1d1a3556ce376ac7aChris Craikvoid Tile::validatePaint() { 500f6a40880028cf495025747229c627f42e25acc66Chris Craik // ONLY CALL while m_atomicSync is locked (at the end of paintBitmap()) 501f6a40880028cf495025747229c627f42e25acc66Chris Craik 502f6a40880028cf495025747229c627f42e25acc66Chris Craik if (!m_dirty) { 503f6a40880028cf495025747229c627f42e25acc66Chris Craik // since after the paint, the tile isn't dirty, 'validate' it - this 504f6a40880028cf495025747229c627f42e25acc66Chris Craik // may happed before or after the transfer queue operation. Only 505f6a40880028cf495025747229c627f42e25acc66Chris Craik // when both have happened, mark as 'ReadyToSwap' 506f6a40880028cf495025747229c627f42e25acc66Chris Craik if (m_state == PaintingStarted) 507f6a40880028cf495025747229c627f42e25acc66Chris Craik m_state = ValidatedUntransferred; 508309ae897e0ad3493fc6acd97a39c631f90580d57Teng-Hui Zhu else if (m_state == TransferredUnvalidated) { 5098abedfb0681eb18f62137fffde000a9dbb75c4d2Teng-Hui Zhu // When the backTexture has been marked pureColor, we will skip the 5108abedfb0681eb18f62137fffde000a9dbb75c4d2Teng-Hui Zhu // transfer and marked as ReadyToSwap, in this case, we don't want 5118abedfb0681eb18f62137fffde000a9dbb75c4d2Teng-Hui Zhu // to reset m_dirty bit to true. 512f6a40880028cf495025747229c627f42e25acc66Chris Craik m_state = ReadyToSwap; 5138abedfb0681eb18f62137fffde000a9dbb75c4d2Teng-Hui Zhu } else { 514d487c56b47c747d3e331ee1892e4c0473363afd2Chris Craik ALOGV("Note: validated tile %p at %d %d, state wasn't paintingstarted or transferred %d", 515f6a40880028cf495025747229c627f42e25acc66Chris Craik this, m_x, m_y, m_state); 5163ef9d5cc655b8274860b8d15441201d3e621baf5Chris Craik // failed transferring, in which case mark dirty (since 5173ef9d5cc655b8274860b8d15441201d3e621baf5Chris Craik // paintBitmap() may have cleared m_dirty) 5183ef9d5cc655b8274860b8d15441201d3e621baf5Chris Craik m_dirty = true; 519f6a40880028cf495025747229c627f42e25acc66Chris Craik } 520f6a40880028cf495025747229c627f42e25acc66Chris Craik } else { 521d487c56b47c747d3e331ee1892e4c0473363afd2Chris Craik ALOGV("Note: paint was unsuccessful."); 522f6a40880028cf495025747229c627f42e25acc66Chris Craik m_state = Unpainted; 523f6a40880028cf495025747229c627f42e25acc66Chris Craik } 524f6a40880028cf495025747229c627f42e25acc66Chris Craik 525f6a40880028cf495025747229c627f42e25acc66Chris Craik} 526f6a40880028cf495025747229c627f42e25acc66Chris Craik 527a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas Roard} // namespace WebCore 528a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas Roard 529a5ffb7c279df240a07658953e1bd5df6d0480cb6Nicolas Roard#endif // USE(ACCELERATED_COMPOSITING) 530