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