OSDN Git Service

d3c1e15f8db3c3607e00b654f23454871be1c008
[android-x86/external-webkit.git] / Source / WebCore / platform / graphics / android / PaintedSurface.cpp
1 /*
2  * Copyright 2011, The Android Open Source Project
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  *  * Redistributions of source code must retain the above copyright
8  *    notice, this list of conditions and the following disclaimer.
9  *  * Redistributions in binary form must reproduce the above copyright
10  *    notice, this list of conditions and the following disclaimer in the
11  *    documentation and/or other materials provided with the distribution.
12  *
13  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY
14  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
17  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24  */
25
26 #include "config.h"
27 #include "PaintedSurface.h"
28
29
30 #include "LayerAndroid.h"
31 #include "TiledTexture.h"
32 #include "TilesManager.h"
33 #include "SkCanvas.h"
34 #include "SkPicture.h"
35
36 #include <cutils/log.h>
37 #include <wtf/CurrentTime.h>
38 #include <wtf/text/CString.h>
39
40 #undef XLOGC
41 #define XLOGC(...) android_printLog(ANDROID_LOG_DEBUG, "PaintedSurface", __VA_ARGS__)
42
43 #ifdef DEBUG
44
45 #undef XLOG
46 #define XLOG(...) android_printLog(ANDROID_LOG_DEBUG, "PaintedSurface", __VA_ARGS__)
47
48 #else
49
50 #undef XLOG
51 #define XLOG(...)
52
53 #endif // DEBUG
54
55 // Allows layers using less than MAX_UNCLIPPED_AREA tiles to
56 // schedule all of them instead of clipping the area with the visible rect.
57 #define MAX_UNCLIPPED_AREA 16
58
59 namespace WebCore {
60
61 PaintedSurface::PaintedSurface()
62     : m_drawingLayer(0)
63     , m_paintingLayer(0)
64     , m_tiledTexture(0)
65     , m_scale(0)
66     , m_pictureUsed(0)
67 {
68     TilesManager::instance()->addPaintedSurface(this);
69 #ifdef DEBUG_COUNT
70     ClassTracker::instance()->increment("PaintedSurface");
71 #endif
72     m_tiledTexture = new DualTiledTexture(this);
73 }
74
75 PaintedSurface::~PaintedSurface()
76 {
77 #ifdef DEBUG_COUNT
78     ClassTracker::instance()->decrement("PaintedSurface");
79 #endif
80     delete m_tiledTexture;
81 }
82
83 void PaintedSurface::prepare(GLWebViewState* state)
84 {
85     XLOG("PS %p has PL %p, DL %p", this, m_paintingLayer, m_drawingLayer);
86     LayerAndroid* paintingLayer = m_paintingLayer;
87     if (!paintingLayer)
88         paintingLayer = m_drawingLayer;
89
90     if (!paintingLayer)
91         return;
92
93     bool startFastSwap = false;
94     if (state->isScrolling()) {
95         // when scrolling, block updates and swap tiles as soon as they're ready
96         startFastSwap = true;
97     }
98
99     XLOG("prepare layer %d %x at scale %.2f",
100          paintingLayer->uniqueId(), paintingLayer,
101          paintingLayer->getScale());
102
103     IntRect visibleArea = computeVisibleArea(paintingLayer);
104
105     m_scale = state->scale();
106
107     // If we do not have text, we may as well limit ourselves to
108     // a scale factor of one... this saves up textures.
109     if (m_scale > 1 && !paintingLayer->hasText())
110         m_scale = 1;
111
112     m_tiledTexture->prepare(state, m_scale, m_pictureUsed != paintingLayer->pictureUsed(),
113                             startFastSwap, visibleArea);
114 }
115
116 bool PaintedSurface::draw()
117 {
118     if (!m_drawingLayer || !m_drawingLayer->needsTexture())
119         return false;
120
121     bool askRedraw = false;
122     if (m_tiledTexture)
123         askRedraw = m_tiledTexture->draw();
124
125     return askRedraw;
126 }
127
128 void PaintedSurface::setPaintingLayer(LayerAndroid* layer, const SkRegion& dirtyArea)
129 {
130     m_paintingLayer = layer;
131     if (m_tiledTexture)
132         m_tiledTexture->update(dirtyArea, layer->picture());
133 }
134
135 bool PaintedSurface::isReady()
136 {
137     if (m_tiledTexture)
138         return m_tiledTexture->isReady();
139     return false;
140 }
141
142 void PaintedSurface::swapTiles()
143 {
144     if (m_tiledTexture)
145         m_tiledTexture->swapTiles();
146 }
147
148 float PaintedSurface::opacity() {
149     if (m_drawingLayer)
150         return m_drawingLayer->drawOpacity();
151     return 1.0;
152 }
153
154 const TransformationMatrix* PaintedSurface::transform() {
155     // used exclusively for drawing, so only use m_drawingLayer
156     if (!m_drawingLayer)
157         return 0;
158
159     return m_drawingLayer->drawTransform();
160 }
161
162 void PaintedSurface::computeTexturesAmount(TexturesResult* result)
163 {
164     if (!m_tiledTexture)
165         return;
166
167     // for now, always done on drawinglayer
168     LayerAndroid* layer = m_drawingLayer;
169
170     if (!layer)
171         return;
172
173     IntRect unclippedArea = layer->unclippedArea();
174     IntRect clippedVisibleArea = layer->visibleArea();
175     // get two numbers here:
176     // - textures needed for a clipped area
177     // - textures needed for an un-clipped area
178     int nbTexturesUnclipped = m_tiledTexture->nbTextures(unclippedArea, m_scale);
179     int nbTexturesClipped = m_tiledTexture->nbTextures(clippedVisibleArea, m_scale);
180
181     // Set kFixedLayers level
182     if (layer->isFixed())
183         result->fixed += nbTexturesClipped;
184
185     // Set kScrollableAndFixedLayers level
186     if (layer->contentIsScrollable()
187         || layer->isFixed())
188         result->scrollable += nbTexturesClipped;
189
190     // Set kClippedTextures level
191     result->clipped += nbTexturesClipped;
192
193     // Set kAllTextures level
194     if (layer->contentIsScrollable())
195         result->full += nbTexturesClipped;
196     else
197         result->full += nbTexturesUnclipped;
198 }
199
200 IntRect PaintedSurface::computeVisibleArea(LayerAndroid* layer) {
201     IntRect area;
202     if (!layer)
203         return area;
204
205     if (!layer->contentIsScrollable()
206         && layer->state()->layersRenderingMode() == GLWebViewState::kAllTextures)
207         area = layer->unclippedArea();
208     else
209         area = layer->visibleArea();
210
211     return area;
212 }
213
214 bool PaintedSurface::owns(BaseTileTexture* texture)
215 {
216     if (m_tiledTexture)
217         return m_tiledTexture->owns(texture);
218     return false;
219 }
220
221 } // namespace WebCore