Home | History | Annotate | Download | only in rendering
      1 /*
      2  * Copyright 2012, 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 #define LOG_TAG "SurfaceCollection"
     27 #define LOG_NDEBUG 1
     28 
     29 #include "config.h"
     30 #include "SurfaceCollection.h"
     31 
     32 #include "AndroidLog.h"
     33 #include "BaseLayerAndroid.h"
     34 #include "ClassTracker.h"
     35 #include "GLWebViewState.h"
     36 #include "PaintTileOperation.h"
     37 #include "Surface.h"
     38 #include "ScrollableLayerAndroid.h"
     39 #include "TilesManager.h"
     40 
     41 namespace WebCore {
     42 
     43 ////////////////////////////////////////////////////////////////////////////////
     44 //                        TILED PAINTING / SURFACES                           //
     45 ////////////////////////////////////////////////////////////////////////////////
     46 
     47 SurfaceCollection::SurfaceCollection(BaseLayerAndroid* layer)
     48         : m_compositedRoot(layer)
     49 {
     50     // layer must be non-null.
     51     SkSafeRef(m_compositedRoot);
     52 
     53     // calculate draw transforms and z values
     54     SkRect visibleRect = SkRect::MakeLTRB(0, 0, 1, 1);
     55     m_compositedRoot->updatePositionsRecursive(visibleRect);
     56 
     57     // allocate surfaces for layers, merging where possible
     58     ALOGV("new tree, allocating surfaces for tree %p", m_baseLayer);
     59 
     60     LayerMergeState layerMergeState(&m_surfaces);
     61     m_compositedRoot->assignSurfaces(&layerMergeState);
     62 
     63     // set the layersurfaces' update count, to be drawn on painted tiles
     64     unsigned int updateCount = TilesManager::instance()->incWebkitContentUpdates();
     65     for (unsigned int i = 0; i < m_surfaces.size(); i++)
     66         m_surfaces[i]->setUpdateCount(updateCount);
     67 
     68 #ifdef DEBUG_COUNT
     69     ClassTracker::instance()->increment("SurfaceCollection");
     70 #endif
     71 }
     72 
     73 SurfaceCollection::~SurfaceCollection()
     74 {
     75     SkSafeUnref(m_compositedRoot);
     76     for (unsigned int i = 0; i < m_surfaces.size(); i++)
     77         SkSafeUnref(m_surfaces[i]);
     78     m_surfaces.clear();
     79 
     80 #ifdef DEBUG_COUNT
     81     ClassTracker::instance()->decrement("SurfaceCollection");
     82 #endif
     83 }
     84 
     85 void SurfaceCollection::prepareGL(const SkRect& visibleContentRect, bool tryToFastBlit)
     86 {
     87     TRACE_METHOD();
     88     updateLayerPositions(visibleContentRect);
     89     bool layerTilesDisabled = m_compositedRoot->state()->isSingleSurfaceRenderingMode();
     90     if (!layerTilesDisabled) {
     91         for (unsigned int i = 0; tryToFastBlit && i < m_surfaces.size(); i++)
     92             tryToFastBlit &= m_surfaces[i]->canUpdateWithBlit();
     93     }
     94     for (unsigned int i = 0; i < m_surfaces.size(); i++)
     95         m_surfaces[i]->prepareGL(layerTilesDisabled, tryToFastBlit);
     96 }
     97 
     98 static inline bool compareSurfaceZ(const Surface* a, const Surface* b)
     99 {
    100     const LayerAndroid* la = a->getFirstLayer();
    101     const LayerAndroid* lb = b->getFirstLayer();
    102 
    103     // swap drawing order if zValue suggests it AND the layers are in the same stacking context
    104     return (la->zValue() > lb->zValue()) && (la->getParent() == lb->getParent());
    105 }
    106 
    107 bool SurfaceCollection::drawGL(const SkRect& visibleContentRect)
    108 {
    109     TRACE_METHOD();
    110 #ifdef DEBUG_COUNT
    111     ClassTracker::instance()->show();
    112 #endif
    113 
    114     bool needsRedraw = false;
    115     updateLayerPositions(visibleContentRect);
    116     bool layerTilesDisabled = m_compositedRoot->state()->isSingleSurfaceRenderingMode();
    117 
    118     // create a duplicate vector of surfaces, sorted by z value
    119     Vector <Surface*> surfaces;
    120     for (unsigned int i = 0; i < m_surfaces.size(); i++)
    121         surfaces.append(m_surfaces[i]);
    122     std::stable_sort(surfaces.begin()+1, surfaces.end(), compareSurfaceZ);
    123 
    124     // draw the sorted vector
    125     for (unsigned int i = 0; i < m_surfaces.size(); i++)
    126         needsRedraw |= surfaces[i]->drawGL(layerTilesDisabled);
    127 
    128     return needsRedraw;
    129 }
    130 
    131 Color SurfaceCollection::getBackgroundColor()
    132 {
    133     return static_cast<BaseLayerAndroid*>(m_compositedRoot)->getBackgroundColor();
    134 }
    135 
    136 void SurfaceCollection::swapTiles()
    137 {
    138     bool calculateFrameworkInvals = !m_compositedRoot->state()->inUnclippedDraw();
    139 
    140     TRACE_METHOD();
    141     for (unsigned int i = 0; i < m_surfaces.size(); i++)
    142          m_surfaces[i]->swapTiles(calculateFrameworkInvals);
    143 }
    144 
    145 void SurfaceCollection::addFrameworkInvals()
    146 {
    147     for (unsigned int i = 0; i < m_surfaces.size(); i++)
    148          m_surfaces[i]->addFrameworkInvals();
    149 }
    150 
    151 bool SurfaceCollection::isReady()
    152 {
    153     // Override layer readiness check for single surface mode
    154     if (m_compositedRoot->state()->isSingleSurfaceRenderingMode())
    155         return m_surfaces[0]->isReady();
    156 
    157     for (unsigned int i = 0; i < m_surfaces.size(); i++) {
    158         if (!m_surfaces[i]->isReady()) {
    159             ALOGV("layer surface %p isn't ready", m_surfaces[i]);
    160             return false;
    161         }
    162     }
    163     return true;
    164 }
    165 
    166 bool SurfaceCollection::isMissingBackgroundContent()
    167 {
    168     // return true when the first surface is missing content (indicating the
    169     // entire viewport isn't covered)
    170     return m_surfaces[0]->isMissingContent();
    171 }
    172 
    173 void SurfaceCollection::removePainterOperations()
    174 {
    175     for (unsigned int i = 0; i < m_surfaces.size(); i++)
    176         TilesManager::instance()->removeOperationsForFilter(new TilePainterFilter(m_surfaces[i]));
    177 }
    178 
    179 void SurfaceCollection::computeTexturesAmount(TexturesResult* result)
    180 {
    181     for (unsigned int i = 0; i < m_surfaces.size(); i++)
    182         m_surfaces[i]->computeTexturesAmount(result);
    183 }
    184 
    185 ////////////////////////////////////////////////////////////////////////////////
    186 //                  RECURSIVE ANIMATION / INVALS / LAYERS                     //
    187 ////////////////////////////////////////////////////////////////////////////////
    188 
    189 void SurfaceCollection::setIsPainting(SurfaceCollection* drawingSurface)
    190 {
    191     if (!drawingSurface)
    192         return;
    193 
    194     for (unsigned int i = 0; i < m_surfaces.size(); i++) {
    195         Surface* newSurface = m_surfaces[i];
    196         if (!newSurface->needsTexture())
    197             continue;
    198 
    199         for (unsigned int j = 0; j < drawingSurface->m_surfaces.size(); j++) {
    200             Surface* oldSurface = drawingSurface->m_surfaces[j];
    201             if (newSurface->tryUpdateSurface(oldSurface))
    202                 break;
    203         }
    204     }
    205 }
    206 
    207 void SurfaceCollection::setIsDrawing()
    208 {
    209     m_compositedRoot->initAnimations();
    210 }
    211 
    212 void SurfaceCollection::mergeInvalsInto(SurfaceCollection* replacementSurface)
    213 {
    214     m_compositedRoot->mergeInvalsInto(replacementSurface->m_compositedRoot);
    215 }
    216 
    217 bool SurfaceCollection::evaluateAnimations(double currentTime)
    218 {
    219     return m_compositedRoot->evaluateAnimations(currentTime);
    220 }
    221 
    222 bool SurfaceCollection::hasCompositedLayers()
    223 {
    224     return m_compositedRoot->countChildren();
    225 }
    226 
    227 bool SurfaceCollection::hasCompositedAnimations()
    228 {
    229     return m_compositedRoot->hasAnimations();
    230 }
    231 
    232 void SurfaceCollection::updateScrollableLayer(int layerId, int x, int y)
    233 {
    234     LayerAndroid* layer = m_compositedRoot->findById(layerId);
    235     if (layer && layer->contentIsScrollable())
    236         static_cast<ScrollableLayerAndroid*>(layer)->scrollTo(x, y);
    237 }
    238 
    239 void SurfaceCollection::updateLayerPositions(const SkRect& visibleContentRect)
    240 {
    241     m_compositedRoot->updatePositionsRecursive(visibleContentRect);
    242 
    243 #ifdef DEBUG
    244     m_compositedRoot->showLayer(0);
    245     ALOGV("We have %d layers, %d textured",
    246           m_compositedRoot->nbLayers(),
    247           m_compositedRoot->nbTexturedLayers());
    248 #endif
    249 }
    250 
    251 int SurfaceCollection::backedSize()
    252 {
    253     int count = 0;
    254     for (unsigned int i = 0; i < m_surfaces.size(); i++) {
    255         if (m_surfaces[i]->needsTexture())
    256             count++;
    257     }
    258     return count;
    259 }
    260 
    261 } // namespace WebCore
    262