2 * Copyright 2010, The Android Open Source Project
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
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.
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.
29 #if USE(ACCELERATED_COMPOSITING)
33 #include "SkBitmapRef.h"
35 #include "TilesManager.h"
38 #include <EGL/eglext.h>
39 #include <GLES2/gl2.h>
40 #include <GLES2/gl2ext.h>
41 #include <cutils/atomic.h>
45 #include <cutils/log.h>
46 #include <wtf/CurrentTime.h>
47 #include <wtf/text/CString.h>
50 #define XLOG(...) android_printLog(ANDROID_LOG_DEBUG, "BaseTile", __VA_ARGS__)
69 , m_lastDirtyPicture(0)
70 , m_lastPaintedPicture(0)
73 ClassTracker::instance()->increment("BaseTile");
81 m_texture->release(this);
84 ClassTracker::instance()->decrement("BaseTile");
88 // All the following functions must be called from the main GL thread.
90 void BaseTile::setContents(TiledPage* page, int x, int y)
92 android::AutoMutex lock(m_atomicSync);
98 void BaseTile::reserveTexture()
100 BackedDoubleBufferedTexture* texture = TilesManager::instance()->getAvailableTexture(this);
102 android::AutoMutex lock(m_atomicSync);
103 if (m_texture != texture) {
104 m_lastPaintedPicture = 0;
110 bool BaseTile::removeTexture(BackedDoubleBufferedTexture* texture)
112 XLOG("%x removeTexture res: %x... page %x", this, m_texture, m_page);
113 // We update atomically, so paintBitmap() can see the correct value
114 android::AutoMutex lock(m_atomicSync);
115 if (m_texture == texture)
120 void BaseTile::setScale(float scale)
122 android::AutoMutex lock(m_atomicSync);
123 if (m_scale != scale)
128 void BaseTile::markAsDirty(int unsigned pictureCount)
130 android::AutoMutex lock(m_atomicSync);
131 m_lastDirtyPicture = pictureCount;
132 if (m_lastPaintedPicture < m_lastDirtyPicture)
136 void BaseTile::setUsable(bool usable)
138 android::AutoMutex lock(m_atomicSync);
143 bool BaseTile::isDirty()
145 android::AutoMutex lock(m_atomicSync);
149 void BaseTile::setUsedLevel(int usedLevel)
152 m_texture->setUsedLevel(usedLevel);
155 void BaseTile::draw(float transparency, SkRect& rect)
157 // No need to mutex protect reads of m_texture as it is only written to by
158 // the consumer thread.
160 XLOG("%x on page %x (%d, %d) trying to draw, but no m_texture!", this, m_page, x(), y());
164 // Early return if set to un-usable in purpose!
166 bool usable = m_usable;
167 bool isTexturePainted = m_lastPaintedPicture;
168 m_atomicSync.unlock();
170 XLOG("early return at BaseTile::draw b/c tile set to unusable !");
173 if (!isTexturePainted) {
174 XLOG("early return at BaseTile::draw b/c tile is not painted !");
178 if (m_texture->x() != m_x || m_texture->y() != m_y)
181 TextureInfo* textureInfo = m_texture->consumerLock();
183 XLOG("%x (%d, %d) trying to draw, but no textureInfo!", this, x(), y());
184 m_texture->consumerRelease();
188 TilesManager::instance()->shader()->drawQuad(rect, textureInfo->m_textureId,
191 m_texture->consumerRelease();
194 bool BaseTile::isTileReady()
198 if (m_texture->owner() != this)
201 android::AutoMutex lock(m_atomicSync);
205 void BaseTile::drawTileInfo(SkCanvas* canvas,
206 BackedDoubleBufferedTexture* texture,
207 int x, int y, float scale)
211 snprintf(str, 256, "(%d,%d) %.2f, tile %x, texture: %x",
212 x, y, scale, this, texture);
213 paint.setARGB(255, 0, 0, 0);
214 canvas->drawText(str, strlen(str), 50, 100, paint);
215 paint.setARGB(255, 255, 0, 0);
216 canvas->drawText(str, strlen(str), 51, 101, paint);
219 // This is called from the texture generation thread
220 void BaseTile::paintBitmap()
223 // We acquire the values below atomically. This ensures that we are reading
224 // values correctly across cores. Further, once we have these values they
225 // can be updated by other threads without consequence.
227 bool dirty = m_dirty;
228 BackedDoubleBufferedTexture* texture = m_texture;
229 float scale = m_scale;
230 m_atomicSync.unlock();
232 if (!dirty || !texture)
237 TiledPage* tiledPage = m_page;
239 texture->producerAcquireContext();
240 TextureInfo* textureInfo = texture->producerLock();
242 // at this point we can safely check the ownership (if the texture got
243 // transferred to another BaseTile under us)
244 if (texture->owner() != this || texture->usedLevel() > 1) {
245 texture->producerRelease();
249 SkSize size = texture->getSize();
250 float tileWidth = size.width();
251 float tileHeight = size.height();
253 const float invScale = 1 / scale;
254 float w = tileWidth * invScale;
255 float h = tileHeight * invScale;
257 SkCanvas* canvas = texture->canvas();
260 canvas->drawColor(tiledPage->glWebViewState()->getBackgroundColor());
261 canvas->scale(scale, scale);
262 canvas->translate(-x * w, -y * h);
264 unsigned int pictureCount = tiledPage->paintBaseLayerContent(canvas);
268 if (TilesManager::instance()->getShowVisualIndicator()) {
270 paint.setARGB(128, 255, 0, 0);
271 paint.setStrokeWidth(3);
272 canvas->drawLine(0, 0, tileWidth, tileHeight, paint);
273 paint.setARGB(128, 0, 255, 0);
274 canvas->drawLine(0, tileHeight, tileWidth, 0, paint);
275 paint.setARGB(128, 0, 0, 255);
276 canvas->drawLine(0, 0, tileWidth, 0, paint);
277 canvas->drawLine(tileWidth, 0, tileWidth, tileHeight, paint);
278 drawTileInfo(canvas, texture, x, y, scale);
281 texture->setTile(x, y);
282 texture->producerUpdate(textureInfo);
285 m_lastPaintedPicture = pictureCount;
286 if (m_lastPaintedPicture >= m_lastDirtyPicture) {
290 m_atomicSync.unlock();
293 } // namespace WebCore
295 #endif // USE(ACCELERATED_COMPOSITING)