1d8be9016b7fda67a91b4ee17b3b2e7ba692ee553Chris Craik/* 2d8be9016b7fda67a91b4ee17b3b2e7ba692ee553Chris Craik * Copyright 2012, The Android Open Source Project 3d8be9016b7fda67a91b4ee17b3b2e7ba692ee553Chris Craik * 4d8be9016b7fda67a91b4ee17b3b2e7ba692ee553Chris Craik * Redistribution and use in source and binary forms, with or without 5d8be9016b7fda67a91b4ee17b3b2e7ba692ee553Chris Craik * modification, are permitted provided that the following conditions 6d8be9016b7fda67a91b4ee17b3b2e7ba692ee553Chris Craik * are met: 7d8be9016b7fda67a91b4ee17b3b2e7ba692ee553Chris Craik * * Redistributions of source code must retain the above copyright 8d8be9016b7fda67a91b4ee17b3b2e7ba692ee553Chris Craik * notice, this list of conditions and the following disclaimer. 9d8be9016b7fda67a91b4ee17b3b2e7ba692ee553Chris Craik * * Redistributions in binary form must reproduce the above copyright 10d8be9016b7fda67a91b4ee17b3b2e7ba692ee553Chris Craik * notice, this list of conditions and the following disclaimer in the 11d8be9016b7fda67a91b4ee17b3b2e7ba692ee553Chris Craik * documentation and/or other materials provided with the distribution. 12d8be9016b7fda67a91b4ee17b3b2e7ba692ee553Chris Craik * 13d8be9016b7fda67a91b4ee17b3b2e7ba692ee553Chris Craik * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY 14d8be9016b7fda67a91b4ee17b3b2e7ba692ee553Chris Craik * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 15d8be9016b7fda67a91b4ee17b3b2e7ba692ee553Chris Craik * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 16d8be9016b7fda67a91b4ee17b3b2e7ba692ee553Chris Craik * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR 17d8be9016b7fda67a91b4ee17b3b2e7ba692ee553Chris Craik * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 18d8be9016b7fda67a91b4ee17b3b2e7ba692ee553Chris Craik * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 19d8be9016b7fda67a91b4ee17b3b2e7ba692ee553Chris Craik * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 20d8be9016b7fda67a91b4ee17b3b2e7ba692ee553Chris Craik * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 21d8be9016b7fda67a91b4ee17b3b2e7ba692ee553Chris Craik * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 22d8be9016b7fda67a91b4ee17b3b2e7ba692ee553Chris Craik * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 23d8be9016b7fda67a91b4ee17b3b2e7ba692ee553Chris Craik * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 24d8be9016b7fda67a91b4ee17b3b2e7ba692ee553Chris Craik */ 25d8be9016b7fda67a91b4ee17b3b2e7ba692ee553Chris Craik 26594c6b805969c2673c84d1d1d1a3556ce376ac7aChris Craik#define LOG_TAG "Surface" 27d487c56b47c747d3e331ee1892e4c0473363afd2Chris Craik#define LOG_NDEBUG 1 28d487c56b47c747d3e331ee1892e4c0473363afd2Chris Craik 29d8be9016b7fda67a91b4ee17b3b2e7ba692ee553Chris Craik#include "config.h" 30594c6b805969c2673c84d1d1d1a3556ce376ac7aChris Craik#include "Surface.h" 31d8be9016b7fda67a91b4ee17b3b2e7ba692ee553Chris Craik 32d487c56b47c747d3e331ee1892e4c0473363afd2Chris Craik#include "AndroidLog.h" 335f0350c3ee327062ec6e22a3935c3bd4534cd15dChris Craik#include "BaseLayerAndroid.h" 34d8be9016b7fda67a91b4ee17b3b2e7ba692ee553Chris Craik#include "ClassTracker.h" 35d8be9016b7fda67a91b4ee17b3b2e7ba692ee553Chris Craik#include "LayerAndroid.h" 36e859a34171f2a36877d95197d118d962078f8aa0John Reck#include "LayerContent.h" 37594c6b805969c2673c84d1d1d1a3556ce376ac7aChris Craik#include "GLWebViewState.h" 38e859a34171f2a36877d95197d118d962078f8aa0John Reck#include "PrerenderedInval.h" 39594c6b805969c2673c84d1d1d1a3556ce376ac7aChris Craik#include "SkCanvas.h" 40594c6b805969c2673c84d1d1d1a3556ce376ac7aChris Craik#include "SurfaceBacking.h" 41e859a34171f2a36877d95197d118d962078f8aa0John Reck#include "Tile.h" 42e859a34171f2a36877d95197d118d962078f8aa0John Reck#include "TileTexture.h" 43d8be9016b7fda67a91b4ee17b3b2e7ba692ee553Chris Craik#include "TilesManager.h" 44d8be9016b7fda67a91b4ee17b3b2e7ba692ee553Chris Craik 45a15d30f54c6edc68da7e82c198b5916dd023ac4dNicolas Roard#include <wtf/text/CString.h> 46a15d30f54c6edc68da7e82c198b5916dd023ac4dNicolas Roard 47594c6b805969c2673c84d1d1d1a3556ce376ac7aChris Craik// Surfaces with an area larger than 2048*2048 should never be unclipped 489e3ead124cc10fcc888a8be7df9949d3d4ba1bb7Teng-Hui Zhu#define MAX_FULL_CONTENT_AREA 4194304 49d8be9016b7fda67a91b4ee17b3b2e7ba692ee553Chris Craik 50d8be9016b7fda67a91b4ee17b3b2e7ba692ee553Chris Craiknamespace WebCore { 51d8be9016b7fda67a91b4ee17b3b2e7ba692ee553Chris Craik 52594c6b805969c2673c84d1d1d1a3556ce376ac7aChris CraikSurface::Surface() 53594c6b805969c2673c84d1d1d1a3556ce376ac7aChris Craik : m_surfaceBacking(0) 540de5188ef06efbbf15051a6ea07ba970253c569cChris Craik , m_needsTexture(false) 550de5188ef06efbbf15051a6ea07ba970253c569cChris Craik , m_hasText(false) 56d8be9016b7fda67a91b4ee17b3b2e7ba692ee553Chris Craik{ 57d8be9016b7fda67a91b4ee17b3b2e7ba692ee553Chris Craik#ifdef DEBUG_COUNT 58594c6b805969c2673c84d1d1d1a3556ce376ac7aChris Craik ClassTracker::instance()->increment("Surface"); 59d8be9016b7fda67a91b4ee17b3b2e7ba692ee553Chris Craik#endif 60d8be9016b7fda67a91b4ee17b3b2e7ba692ee553Chris Craik} 61d8be9016b7fda67a91b4ee17b3b2e7ba692ee553Chris Craik 62594c6b805969c2673c84d1d1d1a3556ce376ac7aChris CraikSurface::~Surface() 63d8be9016b7fda67a91b4ee17b3b2e7ba692ee553Chris Craik{ 64d8be9016b7fda67a91b4ee17b3b2e7ba692ee553Chris Craik for (unsigned int i = 0; i < m_layers.size(); i++) 65d8be9016b7fda67a91b4ee17b3b2e7ba692ee553Chris Craik SkSafeUnref(m_layers[i]); 66594c6b805969c2673c84d1d1d1a3556ce376ac7aChris Craik if (m_surfaceBacking) 67594c6b805969c2673c84d1d1d1a3556ce376ac7aChris Craik SkSafeUnref(m_surfaceBacking); 68d8be9016b7fda67a91b4ee17b3b2e7ba692ee553Chris Craik#ifdef DEBUG_COUNT 69594c6b805969c2673c84d1d1d1a3556ce376ac7aChris Craik ClassTracker::instance()->decrement("Surface"); 70d8be9016b7fda67a91b4ee17b3b2e7ba692ee553Chris Craik#endif 71d8be9016b7fda67a91b4ee17b3b2e7ba692ee553Chris Craik} 72d8be9016b7fda67a91b4ee17b3b2e7ba692ee553Chris Craik 73594c6b805969c2673c84d1d1d1a3556ce376ac7aChris Craikbool Surface::tryUpdateSurface(Surface* oldSurface) 74d8be9016b7fda67a91b4ee17b3b2e7ba692ee553Chris Craik{ 75594c6b805969c2673c84d1d1d1a3556ce376ac7aChris Craik if (!needsTexture() || !oldSurface->needsTexture()) 760de5188ef06efbbf15051a6ea07ba970253c569cChris Craik return false; 770de5188ef06efbbf15051a6ea07ba970253c569cChris Craik 78594c6b805969c2673c84d1d1d1a3556ce376ac7aChris Craik // merge surfaces based on first layer ID 79594c6b805969c2673c84d1d1d1a3556ce376ac7aChris Craik if (getFirstLayer()->uniqueId() != oldSurface->getFirstLayer()->uniqueId()) 800de5188ef06efbbf15051a6ea07ba970253c569cChris Craik return false; 810de5188ef06efbbf15051a6ea07ba970253c569cChris Craik 82594c6b805969c2673c84d1d1d1a3556ce376ac7aChris Craik m_surfaceBacking = oldSurface->m_surfaceBacking; 83594c6b805969c2673c84d1d1d1a3556ce376ac7aChris Craik SkSafeRef(m_surfaceBacking); 84d8be9016b7fda67a91b4ee17b3b2e7ba692ee553Chris Craik 85594c6b805969c2673c84d1d1d1a3556ce376ac7aChris Craik ALOGV("%p taking old SurfBack %p from surface %p, nt %d", 86594c6b805969c2673c84d1d1d1a3556ce376ac7aChris Craik this, m_surfaceBacking, oldSurface, oldSurface->needsTexture()); 870de5188ef06efbbf15051a6ea07ba970253c569cChris Craik 88594c6b805969c2673c84d1d1d1a3556ce376ac7aChris Craik if (!m_surfaceBacking) { 89594c6b805969c2673c84d1d1d1a3556ce376ac7aChris Craik // no SurfBack to inval, so don't worry about it. 900de5188ef06efbbf15051a6ea07ba970253c569cChris Craik return true; 910de5188ef06efbbf15051a6ea07ba970253c569cChris Craik } 920de5188ef06efbbf15051a6ea07ba970253c569cChris Craik 93988183e308148947b034b108c552e719eaff74fbChris Craik SkRegion invalRegion; 94988183e308148947b034b108c552e719eaff74fbChris Craik bool fullInval = false; 95594c6b805969c2673c84d1d1d1a3556ce376ac7aChris Craik if (singleLayer() && oldSurface->singleLayer()) { 960de5188ef06efbbf15051a6ea07ba970253c569cChris Craik // both are single matching layers, simply apply inval 970de5188ef06efbbf15051a6ea07ba970253c569cChris Craik SkRegion* layerInval = getFirstLayer()->getInvalRegion(); 98988183e308148947b034b108c552e719eaff74fbChris Craik invalRegion = *layerInval; 99988183e308148947b034b108c552e719eaff74fbChris Craik 100988183e308148947b034b108c552e719eaff74fbChris Craik if (isBase()) { 101988183e308148947b034b108c552e719eaff74fbChris Craik // the base layer paints outside it's content area to ensure the 102988183e308148947b034b108c552e719eaff74fbChris Craik // viewport is convered, so fully invalidate all tiles if its size 103988183e308148947b034b108c552e719eaff74fbChris Craik // changes to ensure no stale content remains 104988183e308148947b034b108c552e719eaff74fbChris Craik LayerContent* newContent = getFirstLayer()->content(); 105988183e308148947b034b108c552e719eaff74fbChris Craik LayerContent* oldContent = oldSurface->getFirstLayer()->content(); 106988183e308148947b034b108c552e719eaff74fbChris Craik fullInval = newContent->width() != oldContent->width() 107988183e308148947b034b108c552e719eaff74fbChris Craik || newContent->height() != oldContent->height(); 108988183e308148947b034b108c552e719eaff74fbChris Craik } 1090de5188ef06efbbf15051a6ea07ba970253c569cChris Craik } else { 110988183e308148947b034b108c552e719eaff74fbChris Craik fullInval = m_layers.size() != oldSurface->m_layers.size(); 11103dc91a83094490393aea0c809e6c472ab414949Chris Craik if (!fullInval) { 11203dc91a83094490393aea0c809e6c472ab414949Chris Craik for (unsigned int i = 0; i < m_layers.size(); i++) { 1139b0772e730f6ddda6199c42de267fc7742716c00Nicolas Roard if ((m_layers[i]->uniqueId() != oldSurface->m_layers[i]->uniqueId()) 1149b0772e730f6ddda6199c42de267fc7742716c00Nicolas Roard || (m_layers[i]->fullContentAreaMapped() != oldSurface->m_layers[i]->fullContentAreaMapped())) { 11503dc91a83094490393aea0c809e6c472ab414949Chris Craik // layer list has changed, fully invalidate 11603dc91a83094490393aea0c809e6c472ab414949Chris Craik // TODO: partially invalidate based on layer size/position 11703dc91a83094490393aea0c809e6c472ab414949Chris Craik fullInval = true; 11803dc91a83094490393aea0c809e6c472ab414949Chris Craik break; 11903dc91a83094490393aea0c809e6c472ab414949Chris Craik } else if (!m_layers[i]->getInvalRegion()->isEmpty()) { 120594c6b805969c2673c84d1d1d1a3556ce376ac7aChris Craik // merge layer inval - translate the layer's inval region into surface coordinates 121fd977d1127769acd8e0a441cf2ae17de6ab3b979Chris Craik // TODO: handle scale/3d transform mapping 122fd977d1127769acd8e0a441cf2ae17de6ab3b979Chris Craik FloatRect layerPos = m_layers[i]->fullContentAreaMapped(); 123fd977d1127769acd8e0a441cf2ae17de6ab3b979Chris Craik m_layers[i]->getInvalRegion()->translate(layerPos.x(), layerPos.y()); 12403dc91a83094490393aea0c809e6c472ab414949Chris Craik invalRegion.op(*(m_layers[i]->getInvalRegion()), SkRegion::kUnion_Op); 12503dc91a83094490393aea0c809e6c472ab414949Chris Craik } 1260de5188ef06efbbf15051a6ea07ba970253c569cChris Craik } 1270de5188ef06efbbf15051a6ea07ba970253c569cChris Craik } 128988183e308148947b034b108c552e719eaff74fbChris Craik } 1290de5188ef06efbbf15051a6ea07ba970253c569cChris Craik 130988183e308148947b034b108c552e719eaff74fbChris Craik if (fullInval) 131988183e308148947b034b108c552e719eaff74fbChris Craik invalRegion.setRect(-1e8, -1e8, 2e8, 2e8); 132180773f73e86ee60ebacb1a738650b9c319c0212Chris Craik 133988183e308148947b034b108c552e719eaff74fbChris Craik m_surfaceBacking->markAsDirty(invalRegion); 1340de5188ef06efbbf15051a6ea07ba970253c569cChris Craik return true; 1350de5188ef06efbbf15051a6ea07ba970253c569cChris Craik} 1360de5188ef06efbbf15051a6ea07ba970253c569cChris Craik 137594c6b805969c2673c84d1d1d1a3556ce376ac7aChris Craikvoid Surface::addLayer(LayerAndroid* layer, const TransformationMatrix& transform) 138d8be9016b7fda67a91b4ee17b3b2e7ba692ee553Chris Craik{ 139d8be9016b7fda67a91b4ee17b3b2e7ba692ee553Chris Craik m_layers.append(layer); 140d8be9016b7fda67a91b4ee17b3b2e7ba692ee553Chris Craik SkSafeRef(layer); 1410de5188ef06efbbf15051a6ea07ba970253c569cChris Craik 1420de5188ef06efbbf15051a6ea07ba970253c569cChris Craik m_needsTexture |= layer->needsTexture(); 1430de5188ef06efbbf15051a6ea07ba970253c569cChris Craik m_hasText |= layer->hasText(); 1440de5188ef06efbbf15051a6ea07ba970253c569cChris Craik 145fd977d1127769acd8e0a441cf2ae17de6ab3b979Chris Craik // add this layer's size to the surface's area 146fd977d1127769acd8e0a441cf2ae17de6ab3b979Chris Craik // TODO: handle scale/3d transform mapping 147fd977d1127769acd8e0a441cf2ae17de6ab3b979Chris Craik IntRect rect = enclosingIntRect(layer->fullContentAreaMapped()); 1480de5188ef06efbbf15051a6ea07ba970253c569cChris Craik 1490de5188ef06efbbf15051a6ea07ba970253c569cChris Craik if (layer->needsTexture()) { 1509e3ead124cc10fcc888a8be7df9949d3d4ba1bb7Teng-Hui Zhu if (m_fullContentArea.isEmpty()) { 1510de5188ef06efbbf15051a6ea07ba970253c569cChris Craik m_drawTransform = transform; 152fd977d1127769acd8e0a441cf2ae17de6ab3b979Chris Craik m_drawTransform.translate3d(-rect.x(), -rect.y(), 0); 1539e3ead124cc10fcc888a8be7df9949d3d4ba1bb7Teng-Hui Zhu m_fullContentArea = rect; 1540de5188ef06efbbf15051a6ea07ba970253c569cChris Craik } else 1559e3ead124cc10fcc888a8be7df9949d3d4ba1bb7Teng-Hui Zhu m_fullContentArea.unite(rect); 156fd977d1127769acd8e0a441cf2ae17de6ab3b979Chris Craik ALOGV("Surf %p adding LA %p, size " INT_RECT_FORMAT 157fd977d1127769acd8e0a441cf2ae17de6ab3b979Chris Craik " now fullContentArea " INT_RECT_FORMAT, 158fd977d1127769acd8e0a441cf2ae17de6ab3b979Chris Craik this, layer, INT_RECT_ARGS(rect), INT_RECT_ARGS(m_fullContentArea)); 1590de5188ef06efbbf15051a6ea07ba970253c569cChris Craik } 1605f0350c3ee327062ec6e22a3935c3bd4534cd15dChris Craik 1615f0350c3ee327062ec6e22a3935c3bd4534cd15dChris Craik if (isBase()) 1625f0350c3ee327062ec6e22a3935c3bd4534cd15dChris Craik m_background = static_cast<BaseLayerAndroid*>(layer)->getBackgroundColor(); 1630de5188ef06efbbf15051a6ea07ba970253c569cChris Craik} 1640de5188ef06efbbf15051a6ea07ba970253c569cChris Craik 165fd977d1127769acd8e0a441cf2ae17de6ab3b979Chris CraikIntRect Surface::visibleContentArea(bool force3dContentVisible) const 1660de5188ef06efbbf15051a6ea07ba970253c569cChris Craik{ 1670de5188ef06efbbf15051a6ea07ba970253c569cChris Craik if (singleLayer()) 168418e065ccd82593c3f5d49942b0aaee6fac95615Mangesh Ghiware return getFirstLayer()->visibleContentArea(force3dContentVisible); 1690de5188ef06efbbf15051a6ea07ba970253c569cChris Craik 1709e3ead124cc10fcc888a8be7df9949d3d4ba1bb7Teng-Hui Zhu IntRect rect = m_fullContentArea; 1710de5188ef06efbbf15051a6ea07ba970253c569cChris Craik 1729e3ead124cc10fcc888a8be7df9949d3d4ba1bb7Teng-Hui Zhu // clip with the viewport in content coordinate 1739e3ead124cc10fcc888a8be7df9949d3d4ba1bb7Teng-Hui Zhu IntRect contentViewport(TilesManager::instance()->shader()->contentViewport()); 1749e3ead124cc10fcc888a8be7df9949d3d4ba1bb7Teng-Hui Zhu rect.intersect(contentViewport); 1750de5188ef06efbbf15051a6ea07ba970253c569cChris Craik 1760de5188ef06efbbf15051a6ea07ba970253c569cChris Craik // TODO: handle recursive layer clip 1770de5188ef06efbbf15051a6ea07ba970253c569cChris Craik 1780de5188ef06efbbf15051a6ea07ba970253c569cChris Craik return rect; 179d8be9016b7fda67a91b4ee17b3b2e7ba692ee553Chris Craik} 180d8be9016b7fda67a91b4ee17b3b2e7ba692ee553Chris Craik 1819e3ead124cc10fcc888a8be7df9949d3d4ba1bb7Teng-Hui ZhuIntRect Surface::fullContentArea() 182c51715092b8d3be1b51cce8bae61750cbcf342c4Chris Craik{ 183c51715092b8d3be1b51cce8bae61750cbcf342c4Chris Craik if (singleLayer()) 1849e3ead124cc10fcc888a8be7df9949d3d4ba1bb7Teng-Hui Zhu return getFirstLayer()->fullContentArea(); 1859e3ead124cc10fcc888a8be7df9949d3d4ba1bb7Teng-Hui Zhu return m_fullContentArea; 186c51715092b8d3be1b51cce8bae61750cbcf342c4Chris Craik} 187c51715092b8d3be1b51cce8bae61750cbcf342c4Chris Craik 188594c6b805969c2673c84d1d1d1a3556ce376ac7aChris Craikbool Surface::useAggressiveRendering() 189afe34397d6d4655c908f0995e760772980722da3Teng-Hui Zhu{ 190a31d28d03260660f592ad6914f5375b47e823aa5Teng-Hui Zhu // When the background is semi-opaque, 0 < alpha < 255, we had to turn off 191afe34397d6d4655c908f0995e760772980722da3Teng-Hui Zhu // low res to avoid artifacts from double drawing. 192afe34397d6d4655c908f0995e760772980722da3Teng-Hui Zhu // TODO: avoid double drawing for low res tiles. 193afe34397d6d4655c908f0995e760772980722da3Teng-Hui Zhu return isBase() 194afe34397d6d4655c908f0995e760772980722da3Teng-Hui Zhu && (!m_background.alpha() 195afe34397d6d4655c908f0995e760772980722da3Teng-Hui Zhu || !m_background.hasAlpha()); 196afe34397d6d4655c908f0995e760772980722da3Teng-Hui Zhu} 197afe34397d6d4655c908f0995e760772980722da3Teng-Hui Zhu 198e859a34171f2a36877d95197d118d962078f8aa0John Reckvoid Surface::prepareGL(bool layerTilesDisabled, bool updateWithBlit) 199d8be9016b7fda67a91b4ee17b3b2e7ba692ee553Chris Craik{ 200885e650b12d781be054b31ae6221925a0184dc33Chris Craik bool tilesDisabled = layerTilesDisabled && !isBase(); 201594c6b805969c2673c84d1d1d1a3556ce376ac7aChris Craik if (!m_surfaceBacking) { 202594c6b805969c2673c84d1d1d1a3556ce376ac7aChris Craik ALOGV("prepareGL on Surf %p, no SurfBack, needsTexture? %d", 203594c6b805969c2673c84d1d1d1a3556ce376ac7aChris Craik this, m_surfaceBacking, needsTexture()); 2040de5188ef06efbbf15051a6ea07ba970253c569cChris Craik 20544fc37bf2a57490f319e5ddd4f692abf235cb9caNicolas Roard if (needsTexture() || (isBase() && layerTilesDisabled)) 20644fc37bf2a57490f319e5ddd4f692abf235cb9caNicolas Roard m_surfaceBacking = new SurfaceBacking(isBase()); 20744fc37bf2a57490f319e5ddd4f692abf235cb9caNicolas Roard else 2080de5188ef06efbbf15051a6ea07ba970253c569cChris Craik return; 2090de5188ef06efbbf15051a6ea07ba970253c569cChris Craik } 210d8be9016b7fda67a91b4ee17b3b2e7ba692ee553Chris Craik 211885e650b12d781be054b31ae6221925a0184dc33Chris Craik if (tilesDisabled) { 212594c6b805969c2673c84d1d1d1a3556ce376ac7aChris Craik m_surfaceBacking->discardTextures(); 213d8be9016b7fda67a91b4ee17b3b2e7ba692ee553Chris Craik } else { 2140de5188ef06efbbf15051a6ea07ba970253c569cChris Craik bool allowZoom = hasText(); // only allow for scale > 1 if painting vectors 215d8be9016b7fda67a91b4ee17b3b2e7ba692ee553Chris Craik IntRect prepareArea = computePrepareArea(); 2169e3ead124cc10fcc888a8be7df9949d3d4ba1bb7Teng-Hui Zhu IntRect fullArea = fullContentArea(); 2170de5188ef06efbbf15051a6ea07ba970253c569cChris Craik 218a15d30f54c6edc68da7e82c198b5916dd023ac4dNicolas Roard ALOGV("prepareGL on Surf %p with SurfBack %p, %d layers, first layer %s (%d) " 219a15d30f54c6edc68da7e82c198b5916dd023ac4dNicolas Roard "prepareArea(%d, %d - %d x %d) fullArea(%d, %d - %d x %d)", 220a15d30f54c6edc68da7e82c198b5916dd023ac4dNicolas Roard this, m_surfaceBacking, m_layers.size(), 221a15d30f54c6edc68da7e82c198b5916dd023ac4dNicolas Roard getFirstLayer()->subclassName().ascii().data(), 222a15d30f54c6edc68da7e82c198b5916dd023ac4dNicolas Roard getFirstLayer()->uniqueId(), 223a15d30f54c6edc68da7e82c198b5916dd023ac4dNicolas Roard prepareArea.x(), prepareArea.y(), prepareArea.width(), prepareArea.height(), 224a15d30f54c6edc68da7e82c198b5916dd023ac4dNicolas Roard fullArea.x(), fullArea.y(), fullArea.width(), fullArea.height()); 225c51715092b8d3be1b51cce8bae61750cbcf342c4Chris Craik 226594c6b805969c2673c84d1d1d1a3556ce376ac7aChris Craik m_surfaceBacking->prepareGL(getFirstLayer()->state(), allowZoom, 227e859a34171f2a36877d95197d118d962078f8aa0John Reck prepareArea, fullArea, 228e859a34171f2a36877d95197d118d962078f8aa0John Reck this, useAggressiveRendering(), updateWithBlit); 229d30efeae4fa6b64029cfa478fe80981232f502e5John Reck } 230d30efeae4fa6b64029cfa478fe80981232f502e5John Reck for (size_t i = 0; i < m_layers.size(); i++) { 231d30efeae4fa6b64029cfa478fe80981232f502e5John Reck LayerContent* content = m_layers[i]->content(); 232d30efeae4fa6b64029cfa478fe80981232f502e5John Reck if (content) 233d30efeae4fa6b64029cfa478fe80981232f502e5John Reck content->clearPrerenders(); 234d8be9016b7fda67a91b4ee17b3b2e7ba692ee553Chris Craik } 235d8be9016b7fda67a91b4ee17b3b2e7ba692ee553Chris Craik} 236d8be9016b7fda67a91b4ee17b3b2e7ba692ee553Chris Craik 237594c6b805969c2673c84d1d1d1a3556ce376ac7aChris Craikbool Surface::drawGL(bool layerTilesDisabled) 238d8be9016b7fda67a91b4ee17b3b2e7ba692ee553Chris Craik{ 239885e650b12d781be054b31ae6221925a0184dc33Chris Craik bool tilesDisabled = layerTilesDisabled && !isBase(); 240ed2ce36a1fac9f85b65edf34a1c241c2f73d806cNicolas Roard if (singleLayer() && !getFirstLayer()->visible()) 241d8be9016b7fda67a91b4ee17b3b2e7ba692ee553Chris Craik return false; 242d8be9016b7fda67a91b4ee17b3b2e7ba692ee553Chris Craik 24325c25a826222bf0fa1df56f6cfd8582296357b49Chris Craik if (!isBase()) { 24425c25a826222bf0fa1df56f6cfd8582296357b49Chris Craik FloatRect drawClip = getFirstLayer()->drawClip(); 24525c25a826222bf0fa1df56f6cfd8582296357b49Chris Craik if (!singleLayer()) { 24625c25a826222bf0fa1df56f6cfd8582296357b49Chris Craik for (unsigned int i = 1; i < m_layers.size(); i++) 24725c25a826222bf0fa1df56f6cfd8582296357b49Chris Craik drawClip.unite(m_layers[i]->drawClip()); 24825c25a826222bf0fa1df56f6cfd8582296357b49Chris Craik } 24925c25a826222bf0fa1df56f6cfd8582296357b49Chris Craik FloatRect clippingRect = TilesManager::instance()->shader()->rectInInvViewCoord(drawClip); 25025c25a826222bf0fa1df56f6cfd8582296357b49Chris Craik TilesManager::instance()->shader()->clip(clippingRect); 251885e650b12d781be054b31ae6221925a0184dc33Chris Craik } 252d8be9016b7fda67a91b4ee17b3b2e7ba692ee553Chris Craik 253d8be9016b7fda67a91b4ee17b3b2e7ba692ee553Chris Craik bool askRedraw = false; 254594c6b805969c2673c84d1d1d1a3556ce376ac7aChris Craik if (m_surfaceBacking && !tilesDisabled) { 255a15d30f54c6edc68da7e82c198b5916dd023ac4dNicolas Roard ALOGV("drawGL on Surf %p with SurfBack %p, first layer %s (%d)", this, m_surfaceBacking, 256a15d30f54c6edc68da7e82c198b5916dd023ac4dNicolas Roard getFirstLayer()->subclassName().ascii().data(), getFirstLayer()->uniqueId()); 2570de5188ef06efbbf15051a6ea07ba970253c569cChris Craik 258418e065ccd82593c3f5d49942b0aaee6fac95615Mangesh Ghiware bool force3dContentVisible = true; 259418e065ccd82593c3f5d49942b0aaee6fac95615Mangesh Ghiware IntRect drawArea = visibleContentArea(force3dContentVisible); 260594c6b805969c2673c84d1d1d1a3556ce376ac7aChris Craik m_surfaceBacking->drawGL(drawArea, opacity(), drawTransform(), 261868c42d56aae84ed4cd33f9de0d93132e1483ddcTeng-Hui Zhu useAggressiveRendering(), background()); 262d8be9016b7fda67a91b4ee17b3b2e7ba692ee553Chris Craik } 2630de5188ef06efbbf15051a6ea07ba970253c569cChris Craik 2640de5188ef06efbbf15051a6ea07ba970253c569cChris Craik // draw member layers (draws image textures, glextras) 265377dc9f6b46a2ac0f968d9ee8d3c7916f3bf6904Nicolas Roard for (unsigned int i = 0; i < m_layers.size(); i++) { 266377dc9f6b46a2ac0f968d9ee8d3c7916f3bf6904Nicolas Roard if (m_layers[i]->drawGL(tilesDisabled)) { 267377dc9f6b46a2ac0f968d9ee8d3c7916f3bf6904Nicolas Roard m_layers[i]->addDirtyArea(); 268377dc9f6b46a2ac0f968d9ee8d3c7916f3bf6904Nicolas Roard askRedraw = true; 269377dc9f6b46a2ac0f968d9ee8d3c7916f3bf6904Nicolas Roard } 270377dc9f6b46a2ac0f968d9ee8d3c7916f3bf6904Nicolas Roard } 271d8be9016b7fda67a91b4ee17b3b2e7ba692ee553Chris Craik 272d8be9016b7fda67a91b4ee17b3b2e7ba692ee553Chris Craik return askRedraw; 273d8be9016b7fda67a91b4ee17b3b2e7ba692ee553Chris Craik} 274d8be9016b7fda67a91b4ee17b3b2e7ba692ee553Chris Craik 275cfbfb3bbc3ed10f3e061b52c70e5c7935e96a45aChris Craikvoid Surface::swapTiles(bool calculateFrameworkInvals) 276d8be9016b7fda67a91b4ee17b3b2e7ba692ee553Chris Craik{ 277594c6b805969c2673c84d1d1d1a3556ce376ac7aChris Craik if (!m_surfaceBacking) 278d8be9016b7fda67a91b4ee17b3b2e7ba692ee553Chris Craik return; 279d8be9016b7fda67a91b4ee17b3b2e7ba692ee553Chris Craik 280cfbfb3bbc3ed10f3e061b52c70e5c7935e96a45aChris Craik if (m_surfaceBacking->swapTiles() && calculateFrameworkInvals) 281377dc9f6b46a2ac0f968d9ee8d3c7916f3bf6904Nicolas Roard addFrameworkInvals(); 282377dc9f6b46a2ac0f968d9ee8d3c7916f3bf6904Nicolas Roard} 283377dc9f6b46a2ac0f968d9ee8d3c7916f3bf6904Nicolas Roard 284377dc9f6b46a2ac0f968d9ee8d3c7916f3bf6904Nicolas Roardvoid Surface::addFrameworkInvals() 285377dc9f6b46a2ac0f968d9ee8d3c7916f3bf6904Nicolas Roard{ 286377dc9f6b46a2ac0f968d9ee8d3c7916f3bf6904Nicolas Roard // Let's return an inval area to framework that will 287377dc9f6b46a2ac0f968d9ee8d3c7916f3bf6904Nicolas Roard // contain all of our layers' areas 288377dc9f6b46a2ac0f968d9ee8d3c7916f3bf6904Nicolas Roard for (unsigned int i = 0; i < m_layers.size(); i++) 289377dc9f6b46a2ac0f968d9ee8d3c7916f3bf6904Nicolas Roard m_layers[i]->addDirtyArea(); 290d8be9016b7fda67a91b4ee17b3b2e7ba692ee553Chris Craik} 291d8be9016b7fda67a91b4ee17b3b2e7ba692ee553Chris Craik 292594c6b805969c2673c84d1d1d1a3556ce376ac7aChris Craikbool Surface::isReady() 293d8be9016b7fda67a91b4ee17b3b2e7ba692ee553Chris Craik{ 294594c6b805969c2673c84d1d1d1a3556ce376ac7aChris Craik if (!m_surfaceBacking) 295d8be9016b7fda67a91b4ee17b3b2e7ba692ee553Chris Craik return true; 296d8be9016b7fda67a91b4ee17b3b2e7ba692ee553Chris Craik 297594c6b805969c2673c84d1d1d1a3556ce376ac7aChris Craik return m_surfaceBacking->isReady(); 298d8be9016b7fda67a91b4ee17b3b2e7ba692ee553Chris Craik} 299d8be9016b7fda67a91b4ee17b3b2e7ba692ee553Chris Craik 3005f0350c3ee327062ec6e22a3935c3bd4534cd15dChris Craikbool Surface::isMissingContent() 3015f0350c3ee327062ec6e22a3935c3bd4534cd15dChris Craik{ 3025f0350c3ee327062ec6e22a3935c3bd4534cd15dChris Craik if (!m_surfaceBacking) 3035f0350c3ee327062ec6e22a3935c3bd4534cd15dChris Craik return true; 3045f0350c3ee327062ec6e22a3935c3bd4534cd15dChris Craik 3055f0350c3ee327062ec6e22a3935c3bd4534cd15dChris Craik return m_surfaceBacking->isMissingContent(); 3065f0350c3ee327062ec6e22a3935c3bd4534cd15dChris Craik} 3075f0350c3ee327062ec6e22a3935c3bd4534cd15dChris Craik 308e859a34171f2a36877d95197d118d962078f8aa0John Reckbool Surface::canUpdateWithBlit() 309e859a34171f2a36877d95197d118d962078f8aa0John Reck{ 310e859a34171f2a36877d95197d118d962078f8aa0John Reck // If we don't have a texture, we have nothing to update and thus can take 311e859a34171f2a36877d95197d118d962078f8aa0John Reck // the fast path 312e859a34171f2a36877d95197d118d962078f8aa0John Reck if (!needsTexture()) 313e859a34171f2a36877d95197d118d962078f8aa0John Reck return true; 314e859a34171f2a36877d95197d118d962078f8aa0John Reck // If we have a surface backing that isn't ready, we can't update with a blit 315e859a34171f2a36877d95197d118d962078f8aa0John Reck // If it is ready, then check to see if it is dirty. We can only call isDirty() 316e859a34171f2a36877d95197d118d962078f8aa0John Reck // if isReady() returns true 317e859a34171f2a36877d95197d118d962078f8aa0John Reck if (!m_surfaceBacking) 318e859a34171f2a36877d95197d118d962078f8aa0John Reck return false; 319e859a34171f2a36877d95197d118d962078f8aa0John Reck if (!m_surfaceBacking->isReady()) 320e859a34171f2a36877d95197d118d962078f8aa0John Reck return false; 321e859a34171f2a36877d95197d118d962078f8aa0John Reck if (!m_surfaceBacking->isDirty()) 322e859a34171f2a36877d95197d118d962078f8aa0John Reck return true; 323e859a34171f2a36877d95197d118d962078f8aa0John Reck if (!singleLayer()) 324e859a34171f2a36877d95197d118d962078f8aa0John Reck return false; 325e859a34171f2a36877d95197d118d962078f8aa0John Reck return getFirstLayer()->canUpdateWithBlit(); 326e859a34171f2a36877d95197d118d962078f8aa0John Reck} 327e859a34171f2a36877d95197d118d962078f8aa0John Reck 328e859a34171f2a36877d95197d118d962078f8aa0John ReckIntRect Surface::computePrepareArea() 329e859a34171f2a36877d95197d118d962078f8aa0John Reck{ 330d8be9016b7fda67a91b4ee17b3b2e7ba692ee553Chris Craik IntRect area; 331d8be9016b7fda67a91b4ee17b3b2e7ba692ee553Chris Craik 3320de5188ef06efbbf15051a6ea07ba970253c569cChris Craik if (!getFirstLayer()->contentIsScrollable() 333885e650b12d781be054b31ae6221925a0184dc33Chris Craik && !isBase() 3340de5188ef06efbbf15051a6ea07ba970253c569cChris Craik && getFirstLayer()->state()->layersRenderingMode() == GLWebViewState::kAllTextures) { 3350de5188ef06efbbf15051a6ea07ba970253c569cChris Craik 3369e3ead124cc10fcc888a8be7df9949d3d4ba1bb7Teng-Hui Zhu area = fullContentArea(); 337d8be9016b7fda67a91b4ee17b3b2e7ba692ee553Chris Craik 338d8be9016b7fda67a91b4ee17b3b2e7ba692ee553Chris Craik double total = ((double) area.width()) * ((double) area.height()); 3399e3ead124cc10fcc888a8be7df9949d3d4ba1bb7Teng-Hui Zhu if (total > MAX_FULL_CONTENT_AREA) 3409e3ead124cc10fcc888a8be7df9949d3d4ba1bb7Teng-Hui Zhu area = visibleContentArea(); 341e859a34171f2a36877d95197d118d962078f8aa0John Reck } else 3429e3ead124cc10fcc888a8be7df9949d3d4ba1bb7Teng-Hui Zhu area = visibleContentArea(); 343d8be9016b7fda67a91b4ee17b3b2e7ba692ee553Chris Craik 344d8be9016b7fda67a91b4ee17b3b2e7ba692ee553Chris Craik return area; 345d8be9016b7fda67a91b4ee17b3b2e7ba692ee553Chris Craik} 346d8be9016b7fda67a91b4ee17b3b2e7ba692ee553Chris Craik 347594c6b805969c2673c84d1d1d1a3556ce376ac7aChris Craikvoid Surface::computeTexturesAmount(TexturesResult* result) 348d8be9016b7fda67a91b4ee17b3b2e7ba692ee553Chris Craik{ 349594c6b805969c2673c84d1d1d1a3556ce376ac7aChris Craik if (!m_surfaceBacking || isBase()) 350d8be9016b7fda67a91b4ee17b3b2e7ba692ee553Chris Craik return; 351d8be9016b7fda67a91b4ee17b3b2e7ba692ee553Chris Craik 352bfd7e70d96a769e5d62fb5c9148b5c810a8bef65Chris Craik 353bfd7e70d96a769e5d62fb5c9148b5c810a8bef65Chris Craik LayerAndroid* layer = 0; 354bfd7e70d96a769e5d62fb5c9148b5c810a8bef65Chris Craik if (singleLayer()) 355bfd7e70d96a769e5d62fb5c9148b5c810a8bef65Chris Craik layer = getFirstLayer(); 356bfd7e70d96a769e5d62fb5c9148b5c810a8bef65Chris Craik 357bfd7e70d96a769e5d62fb5c9148b5c810a8bef65Chris Craik m_surfaceBacking->computeTexturesAmount(result, visibleContentArea(), 358bfd7e70d96a769e5d62fb5c9148b5c810a8bef65Chris Craik fullContentArea(), layer); 359d8be9016b7fda67a91b4ee17b3b2e7ba692ee553Chris Craik} 360d8be9016b7fda67a91b4ee17b3b2e7ba692ee553Chris Craik 361594c6b805969c2673c84d1d1d1a3556ce376ac7aChris Craikbool Surface::isBase() 362885e650b12d781be054b31ae6221925a0184dc33Chris Craik{ 363594c6b805969c2673c84d1d1d1a3556ce376ac7aChris Craik // base layer surface 364885e650b12d781be054b31ae6221925a0184dc33Chris Craik // - doesn't use layer tiles (disables blending, doesn't compute textures amount) 365885e650b12d781be054b31ae6221925a0184dc33Chris Craik // - ignores clip rects 366885e650b12d781be054b31ae6221925a0184dc33Chris Craik // - only prepares clippedArea 367885e650b12d781be054b31ae6221925a0184dc33Chris Craik return getFirstLayer()->subclassType() == LayerAndroid::BaseLayer; 368885e650b12d781be054b31ae6221925a0184dc33Chris Craik} 369885e650b12d781be054b31ae6221925a0184dc33Chris Craik 37064d72d82692e48f595e7a31ac2a1680f11d9186bChris Craikbool Surface::paint(SkCanvas* canvas) 371d8be9016b7fda67a91b4ee17b3b2e7ba692ee553Chris Craik{ 3720de5188ef06efbbf15051a6ea07ba970253c569cChris Craik if (singleLayer()) { 3730de5188ef06efbbf15051a6ea07ba970253c569cChris Craik getFirstLayer()->contentDraw(canvas, Layer::UnmergedLayers); 374885e650b12d781be054b31ae6221925a0184dc33Chris Craik 375885e650b12d781be054b31ae6221925a0184dc33Chris Craik // TODO: double buffer by disabling SurfaceCollection swaps and position 376885e650b12d781be054b31ae6221925a0184dc33Chris Craik // updates until painting complete 377885e650b12d781be054b31ae6221925a0184dc33Chris Craik 378885e650b12d781be054b31ae6221925a0184dc33Chris Craik // In single surface mode, draw layer content onto the base layer 379885e650b12d781be054b31ae6221925a0184dc33Chris Craik if (isBase() 380885e650b12d781be054b31ae6221925a0184dc33Chris Craik && getFirstLayer()->countChildren() 38145c2747dcc0151ebf5a296118c2d3c8f69ab4f68Teng-Hui Zhu && getFirstLayer()->state()->isSingleSurfaceRenderingMode()) { 382425ef23631e3468c61a5740dd4e4bae3052cec48Chris Craik for (int i = 0; i < getFirstLayer()->countChildren(); i++) 38344fc37bf2a57490f319e5ddd4f692abf235cb9caNicolas Roard getFirstLayer()->getChild(i)->drawCanvas(canvas, true, Layer::FlattenedLayers); 38444fc37bf2a57490f319e5ddd4f692abf235cb9caNicolas Roard } 3850de5188ef06efbbf15051a6ea07ba970253c569cChris Craik } else { 3860de5188ef06efbbf15051a6ea07ba970253c569cChris Craik SkAutoCanvasRestore acr(canvas, true); 3870de5188ef06efbbf15051a6ea07ba970253c569cChris Craik SkMatrix matrix; 3880de5188ef06efbbf15051a6ea07ba970253c569cChris Craik GLUtils::toSkMatrix(matrix, m_drawTransform); 3890de5188ef06efbbf15051a6ea07ba970253c569cChris Craik 3900de5188ef06efbbf15051a6ea07ba970253c569cChris Craik SkMatrix inverse; 3910de5188ef06efbbf15051a6ea07ba970253c569cChris Craik inverse.reset(); 3920de5188ef06efbbf15051a6ea07ba970253c569cChris Craik matrix.invert(&inverse); 393d8be9016b7fda67a91b4ee17b3b2e7ba692ee553Chris Craik 3940de5188ef06efbbf15051a6ea07ba970253c569cChris Craik SkMatrix canvasMatrix = canvas->getTotalMatrix(); 3950de5188ef06efbbf15051a6ea07ba970253c569cChris Craik inverse.postConcat(canvasMatrix); 3960de5188ef06efbbf15051a6ea07ba970253c569cChris Craik canvas->setMatrix(inverse); 397d8be9016b7fda67a91b4ee17b3b2e7ba692ee553Chris Craik 3980de5188ef06efbbf15051a6ea07ba970253c569cChris Craik for (unsigned int i=0; i<m_layers.size(); i++) 3990de5188ef06efbbf15051a6ea07ba970253c569cChris Craik m_layers[i]->drawCanvas(canvas, false, Layer::MergedLayers); 4000de5188ef06efbbf15051a6ea07ba970253c569cChris Craik } 401d8be9016b7fda67a91b4ee17b3b2e7ba692ee553Chris Craik return true; 402d8be9016b7fda67a91b4ee17b3b2e7ba692ee553Chris Craik} 403d8be9016b7fda67a91b4ee17b3b2e7ba692ee553Chris Craik 404594c6b805969c2673c84d1d1d1a3556ce376ac7aChris Craikfloat Surface::opacity() 405d8be9016b7fda67a91b4ee17b3b2e7ba692ee553Chris Craik{ 4060de5188ef06efbbf15051a6ea07ba970253c569cChris Craik if (singleLayer()) 4070bf51548ba11c8d43a852f8c50ceca5d97405f65John Reck return getFirstLayer()->drawOpacity(); 4080de5188ef06efbbf15051a6ea07ba970253c569cChris Craik return 1.0; 4090de5188ef06efbbf15051a6ea07ba970253c569cChris Craik} 4100de5188ef06efbbf15051a6ea07ba970253c569cChris Craik 411594c6b805969c2673c84d1d1d1a3556ce376ac7aChris CraikColor* Surface::background() 412afe34397d6d4655c908f0995e760772980722da3Teng-Hui Zhu{ 413afe34397d6d4655c908f0995e760772980722da3Teng-Hui Zhu if (!isBase() || !m_background.isValid()) 414afe34397d6d4655c908f0995e760772980722da3Teng-Hui Zhu return 0; 415afe34397d6d4655c908f0995e760772980722da3Teng-Hui Zhu return &m_background; 416afe34397d6d4655c908f0995e760772980722da3Teng-Hui Zhu} 417afe34397d6d4655c908f0995e760772980722da3Teng-Hui Zhu 418e859a34171f2a36877d95197d118d962078f8aa0John Reckbool Surface::blitFromContents(Tile* tile) 419e859a34171f2a36877d95197d118d962078f8aa0John Reck{ 420e859a34171f2a36877d95197d118d962078f8aa0John Reck if (!singleLayer() || !tile || !getFirstLayer() || !getFirstLayer()->content()) 421e859a34171f2a36877d95197d118d962078f8aa0John Reck return false; 422e859a34171f2a36877d95197d118d962078f8aa0John Reck 4230c274b96c2dfb5a83b12a99f1ca9069378f73bdbChris Craik if (tile->frontTexture() != tile->lastDrawnTexture()) { 4240c274b96c2dfb5a83b12a99f1ca9069378f73bdbChris Craik // the below works around an issue where glTexSubImage2d can't update a 4250c274b96c2dfb5a83b12a99f1ca9069378f73bdbChris Craik // texture that hasn't drawn yet by drawing it off screen. 4260c274b96c2dfb5a83b12a99f1ca9069378f73bdbChris Craik // glFlush() and glFinish() work also, but are likely more wasteful. 4270c274b96c2dfb5a83b12a99f1ca9069378f73bdbChris Craik SkRect rect = SkRect::MakeXYWH(-100, -100, 0, 0); 4280c274b96c2dfb5a83b12a99f1ca9069378f73bdbChris Craik FloatRect fillPortion(0, 0, 0, 0); 4290c274b96c2dfb5a83b12a99f1ca9069378f73bdbChris Craik tile->frontTexture()->drawGL(false, rect, 1.0f, 0, false, true, fillPortion); 4300c274b96c2dfb5a83b12a99f1ca9069378f73bdbChris Craik } 431e859a34171f2a36877d95197d118d962078f8aa0John Reck LayerContent* content = getFirstLayer()->content(); 432e859a34171f2a36877d95197d118d962078f8aa0John Reck // Extract the dirty rect from the region. Note that this is *NOT* constrained 433e859a34171f2a36877d95197d118d962078f8aa0John Reck // to this tile 434e859a34171f2a36877d95197d118d962078f8aa0John Reck IntRect dirtyRect = tile->dirtyArea().getBounds(); 435d30efeae4fa6b64029cfa478fe80981232f502e5John Reck IntRect tileRect = IntRect(tile->x() * TilesManager::tileWidth(), 436d30efeae4fa6b64029cfa478fe80981232f502e5John Reck tile->y() * TilesManager::tileHeight(), 437d30efeae4fa6b64029cfa478fe80981232f502e5John Reck TilesManager::tileWidth(), 438d30efeae4fa6b64029cfa478fe80981232f502e5John Reck TilesManager::tileHeight()); 439d30efeae4fa6b64029cfa478fe80981232f502e5John Reck FloatRect tileRectInDoc = tileRect; 440d30efeae4fa6b64029cfa478fe80981232f502e5John Reck tileRectInDoc.scale(1 / tile->scale()); 441d30efeae4fa6b64029cfa478fe80981232f502e5John Reck dirtyRect.intersect(enclosingIntRect(tileRectInDoc)); 442e859a34171f2a36877d95197d118d962078f8aa0John Reck PrerenderedInval* prerenderedInval = content->prerenderForRect(dirtyRect); 443e859a34171f2a36877d95197d118d962078f8aa0John Reck if (!prerenderedInval || prerenderedInval->bitmap.isNull()) 444e859a34171f2a36877d95197d118d962078f8aa0John Reck return false; 445e859a34171f2a36877d95197d118d962078f8aa0John Reck SkBitmap sourceBitmap = prerenderedInval->bitmap; 446e859a34171f2a36877d95197d118d962078f8aa0John Reck // Calculate the screen rect that is dirty, then intersect it with the 447e859a34171f2a36877d95197d118d962078f8aa0John Reck // tile's screen rect so that we end up with the pixels we need to blit 448e859a34171f2a36877d95197d118d962078f8aa0John Reck FloatRect screenDirty = dirtyRect; 449e859a34171f2a36877d95197d118d962078f8aa0John Reck screenDirty.scale(tile->scale()); 450e859a34171f2a36877d95197d118d962078f8aa0John Reck IntRect enclosingScreenDirty = enclosingIntRect(screenDirty); 451e859a34171f2a36877d95197d118d962078f8aa0John Reck enclosingScreenDirty.intersect(tileRect); 452e859a34171f2a36877d95197d118d962078f8aa0John Reck if (enclosingScreenDirty.isEmpty()) 453e859a34171f2a36877d95197d118d962078f8aa0John Reck return false; 454e859a34171f2a36877d95197d118d962078f8aa0John Reck // Make sure the screen area we want to blit is contained by the 455e859a34171f2a36877d95197d118d962078f8aa0John Reck // prerendered screen area 456e859a34171f2a36877d95197d118d962078f8aa0John Reck if (!prerenderedInval->screenArea.contains(enclosingScreenDirty)) { 457e859a34171f2a36877d95197d118d962078f8aa0John Reck ALOGD("prerendered->screenArea " INT_RECT_FORMAT " doesn't contain " 458e859a34171f2a36877d95197d118d962078f8aa0John Reck "enclosingScreenDirty " INT_RECT_FORMAT, 459e859a34171f2a36877d95197d118d962078f8aa0John Reck INT_RECT_ARGS(prerenderedInval->screenArea), 460e859a34171f2a36877d95197d118d962078f8aa0John Reck INT_RECT_ARGS(enclosingScreenDirty)); 461e859a34171f2a36877d95197d118d962078f8aa0John Reck return false; 462e859a34171f2a36877d95197d118d962078f8aa0John Reck } 463e859a34171f2a36877d95197d118d962078f8aa0John Reck IntPoint origin = prerenderedInval->screenArea.location(); 464e859a34171f2a36877d95197d118d962078f8aa0John Reck SkBitmap subset; 465e859a34171f2a36877d95197d118d962078f8aa0John Reck subset.setConfig(sourceBitmap.config(), enclosingScreenDirty.width(), 466e859a34171f2a36877d95197d118d962078f8aa0John Reck enclosingScreenDirty.height()); 467e859a34171f2a36877d95197d118d962078f8aa0John Reck subset.allocPixels(); 468e859a34171f2a36877d95197d118d962078f8aa0John Reck 469e859a34171f2a36877d95197d118d962078f8aa0John Reck int topOffset = enclosingScreenDirty.y() - prerenderedInval->screenArea.y(); 470e859a34171f2a36877d95197d118d962078f8aa0John Reck int leftOffset = enclosingScreenDirty.x() - prerenderedInval->screenArea.x(); 471e859a34171f2a36877d95197d118d962078f8aa0John Reck if (!GLUtils::deepCopyBitmapSubset(sourceBitmap, subset, leftOffset, topOffset)) 472e859a34171f2a36877d95197d118d962078f8aa0John Reck return false; 473e859a34171f2a36877d95197d118d962078f8aa0John Reck // Now upload 474e859a34171f2a36877d95197d118d962078f8aa0John Reck SkIRect textureInval = SkIRect::MakeXYWH(enclosingScreenDirty.x() - tileRect.x(), 475e859a34171f2a36877d95197d118d962078f8aa0John Reck enclosingScreenDirty.y() - tileRect.y(), 476e859a34171f2a36877d95197d118d962078f8aa0John Reck enclosingScreenDirty.width(), 477e859a34171f2a36877d95197d118d962078f8aa0John Reck enclosingScreenDirty.height()); 478e859a34171f2a36877d95197d118d962078f8aa0John Reck GLUtils::updateTextureWithBitmap(tile->frontTexture()->m_ownTextureId, 479e859a34171f2a36877d95197d118d962078f8aa0John Reck subset, textureInval); 480e859a34171f2a36877d95197d118d962078f8aa0John Reck tile->onBlitUpdate(); 481e859a34171f2a36877d95197d118d962078f8aa0John Reck return true; 482e859a34171f2a36877d95197d118d962078f8aa0John Reck} 483e859a34171f2a36877d95197d118d962078f8aa0John Reck 484594c6b805969c2673c84d1d1d1a3556ce376ac7aChris Craikconst TransformationMatrix* Surface::drawTransform() 4850de5188ef06efbbf15051a6ea07ba970253c569cChris Craik{ 486594c6b805969c2673c84d1d1d1a3556ce376ac7aChris Craik // single layer surfaces query the layer's draw transform, while multi-layer 487594c6b805969c2673c84d1d1d1a3556ce376ac7aChris Craik // surfaces copy the draw transform once, during initialization 488594c6b805969c2673c84d1d1d1a3556ce376ac7aChris Craik // TODO: support fixed multi-layer surfaces by querying the changing drawTransform 4890de5188ef06efbbf15051a6ea07ba970253c569cChris Craik if (singleLayer()) 4900de5188ef06efbbf15051a6ea07ba970253c569cChris Craik return getFirstLayer()->drawTransform(); 4910de5188ef06efbbf15051a6ea07ba970253c569cChris Craik 4920de5188ef06efbbf15051a6ea07ba970253c569cChris Craik return &m_drawTransform; 493d8be9016b7fda67a91b4ee17b3b2e7ba692ee553Chris Craik} 494d8be9016b7fda67a91b4ee17b3b2e7ba692ee553Chris Craik 495d8be9016b7fda67a91b4ee17b3b2e7ba692ee553Chris Craik} // namespace WebCore 496