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// Layers with an area larger than 2048*2048 should never be unclipped 56#define MAX_UNCLIPPED_AREA 4194304 57 58namespace WebCore { 59 60PaintedSurface::PaintedSurface() 61 : m_drawingLayer(0) 62 , m_paintingLayer(0) 63 , m_tiledTexture(0) 64 , m_scale(0) 65 , m_pictureUsed(0) 66{ 67 TilesManager::instance()->addPaintedSurface(this); 68#ifdef DEBUG_COUNT 69 ClassTracker::instance()->increment("PaintedSurface"); 70#endif 71 m_tiledTexture = new DualTiledTexture(this); 72} 73 74PaintedSurface::~PaintedSurface() 75{ 76#ifdef DEBUG_COUNT 77 ClassTracker::instance()->decrement("PaintedSurface"); 78#endif 79 delete m_tiledTexture; 80} 81 82void PaintedSurface::prepare(GLWebViewState* state) 83{ 84 XLOG("PS %p has PL %p, DL %p", this, m_paintingLayer, m_drawingLayer); 85 LayerAndroid* paintingLayer = m_paintingLayer; 86 if (!paintingLayer) 87 paintingLayer = m_drawingLayer; 88 89 if (!paintingLayer) 90 return; 91 92 bool startFastSwap = false; 93 if (state->isScrolling()) { 94 // when scrolling, block updates and swap tiles as soon as they're ready 95 startFastSwap = true; 96 } 97 98 XLOG("prepare layer %d %x at scale %.2f", 99 paintingLayer->uniqueId(), paintingLayer, 100 paintingLayer->getScale()); 101 102 IntRect visibleArea = computeVisibleArea(paintingLayer); 103 104 m_scale = state->scale(); 105 106 // If we do not have text, we may as well limit ourselves to 107 // a scale factor of one... this saves up textures. 108 if (m_scale > 1 && !paintingLayer->hasText()) 109 m_scale = 1; 110 111 m_tiledTexture->prepare(state, m_scale, m_pictureUsed != paintingLayer->pictureUsed(), 112 startFastSwap, visibleArea); 113} 114 115bool PaintedSurface::draw() 116{ 117 if (!m_drawingLayer || !m_drawingLayer->needsTexture()) 118 return false; 119 120 bool askRedraw = false; 121 if (m_tiledTexture) 122 askRedraw = m_tiledTexture->draw(); 123 124 return askRedraw; 125} 126 127void PaintedSurface::setPaintingLayer(LayerAndroid* layer, const SkRegion& dirtyArea) 128{ 129 m_paintingLayer = layer; 130 if (m_tiledTexture) 131 m_tiledTexture->update(dirtyArea, layer->picture()); 132} 133 134bool PaintedSurface::isReady() 135{ 136 if (m_tiledTexture) 137 return m_tiledTexture->isReady(); 138 return false; 139} 140 141void PaintedSurface::swapTiles() 142{ 143 if (m_tiledTexture) 144 m_tiledTexture->swapTiles(); 145} 146 147float PaintedSurface::opacity() { 148 if (m_drawingLayer) 149 return m_drawingLayer->drawOpacity(); 150 return 1.0; 151} 152 153const TransformationMatrix* PaintedSurface::transform() { 154 // used exclusively for drawing, so only use m_drawingLayer 155 if (!m_drawingLayer) 156 return 0; 157 158 return m_drawingLayer->drawTransform(); 159} 160 161void PaintedSurface::computeTexturesAmount(TexturesResult* result) 162{ 163 if (!m_tiledTexture) 164 return; 165 166 // for now, always done on drawinglayer 167 LayerAndroid* layer = m_drawingLayer; 168 169 if (!layer) 170 return; 171 172 IntRect unclippedArea = layer->unclippedArea(); 173 IntRect clippedVisibleArea = layer->visibleArea(); 174 // get two numbers here: 175 // - textures needed for a clipped area 176 // - textures needed for an un-clipped area 177 int nbTexturesUnclipped = m_tiledTexture->nbTextures(unclippedArea, m_scale); 178 int nbTexturesClipped = m_tiledTexture->nbTextures(clippedVisibleArea, m_scale); 179 180 // Set kFixedLayers level 181 if (layer->isFixed()) 182 result->fixed += nbTexturesClipped; 183 184 // Set kScrollableAndFixedLayers level 185 if (layer->contentIsScrollable() 186 || layer->isFixed()) 187 result->scrollable += nbTexturesClipped; 188 189 // Set kClippedTextures level 190 result->clipped += nbTexturesClipped; 191 192 // Set kAllTextures level 193 if (layer->contentIsScrollable()) 194 result->full += nbTexturesClipped; 195 else 196 result->full += nbTexturesUnclipped; 197} 198 199IntRect PaintedSurface::computeVisibleArea(LayerAndroid* layer) { 200 IntRect area; 201 if (!layer) 202 return area; 203 204 if (!layer->contentIsScrollable() 205 && layer->state()->layersRenderingMode() == GLWebViewState::kAllTextures) { 206 area = layer->unclippedArea(); 207 double total = ((double) area.width()) * ((double) area.height()); 208 if (total > MAX_UNCLIPPED_AREA) 209 area = layer->visibleArea(); 210 } else { 211 area = layer->visibleArea(); 212 } 213 214 return area; 215} 216 217bool PaintedSurface::owns(BaseTileTexture* texture) 218{ 219 if (m_tiledTexture) 220 return m_tiledTexture->owns(texture); 221 return false; 222} 223 224} // namespace WebCore 225