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 bool SurfaceCollection::drawGL(const SkRect& visibleContentRect)
     99 {
    100     TRACE_METHOD();
    101 #ifdef DEBUG_COUNT
    102     ClassTracker::instance()->show();
    103 #endif
    104 
    105     updateLayerPositions(visibleContentRect);
    106     bool layerTilesDisabled = m_compositedRoot->state()->isSingleSurfaceRenderingMode();
    107 
    108     return m_compositedRoot->drawTreeSurfacesGL();
    109 }
    110 
    111 Color SurfaceCollection::getBackgroundColor()
    112 {
    113     return static_cast<BaseLayerAndroid*>(m_compositedRoot)->getBackgroundColor();
    114 }
    115 
    116 void SurfaceCollection::swapTiles()
    117 {
    118     bool calculateFrameworkInvals = !m_compositedRoot->state()->inUnclippedDraw();
    119 
    120     TRACE_METHOD();
    121     for (unsigned int i = 0; i < m_surfaces.size(); i++)
    122          m_surfaces[i]->swapTiles(calculateFrameworkInvals);
    123 }
    124 
    125 void SurfaceCollection::addFrameworkInvals()
    126 {
    127     for (unsigned int i = 0; i < m_surfaces.size(); i++)
    128          m_surfaces[i]->addFrameworkInvals();
    129 }
    130 
    131 bool SurfaceCollection::isReady()
    132 {
    133     // Override layer readiness check for single surface mode
    134     if (m_compositedRoot->state()->isSingleSurfaceRenderingMode())
    135         return m_surfaces[0]->isReady();
    136 
    137     for (unsigned int i = 0; i < m_surfaces.size(); i++) {
    138         if (!m_surfaces[i]->isReady()) {
    139             ALOGV("layer surface %p isn't ready", m_surfaces[i]);
    140             return false;
    141         }
    142     }
    143     return true;
    144 }
    145 
    146 bool SurfaceCollection::isMissingBackgroundContent()
    147 {
    148     // return true when the first surface is missing content (indicating the
    149     // entire viewport isn't covered)
    150     return m_surfaces[0]->isMissingContent();
    151 }
    152 
    153 void SurfaceCollection::removePainterOperations()
    154 {
    155     for (unsigned int i = 0; i < m_surfaces.size(); i++)
    156         TilesManager::instance()->removeOperationsForFilter(new TilePainterFilter(m_surfaces[i]));
    157 }
    158 
    159 void SurfaceCollection::computeTexturesAmount(TexturesResult* result)
    160 {
    161     for (unsigned int i = 0; i < m_surfaces.size(); i++)
    162         m_surfaces[i]->computeTexturesAmount(result);
    163 }
    164 
    165 ////////////////////////////////////////////////////////////////////////////////
    166 //                  RECURSIVE ANIMATION / INVALS / LAYERS                     //
    167 ////////////////////////////////////////////////////////////////////////////////
    168 
    169 void SurfaceCollection::setIsPainting(SurfaceCollection* drawingSurface)
    170 {
    171     if (!drawingSurface)
    172         return;
    173 
    174     for (unsigned int i = 0; i < m_surfaces.size(); i++) {
    175         Surface* newSurface = m_surfaces[i];
    176         if (!newSurface->needsTexture())
    177             continue;
    178 
    179         for (unsigned int j = 0; j < drawingSurface->m_surfaces.size(); j++) {
    180             Surface* oldSurface = drawingSurface->m_surfaces[j];
    181             if (newSurface->tryUpdateSurface(oldSurface))
    182                 break;
    183         }
    184     }
    185 }
    186 
    187 void SurfaceCollection::setIsDrawing()
    188 {
    189     m_compositedRoot->initAnimations();
    190 }
    191 
    192 void SurfaceCollection::mergeInvalsInto(SurfaceCollection* replacementSurface)
    193 {
    194     m_compositedRoot->mergeInvalsInto(replacementSurface->m_compositedRoot);
    195 }
    196 
    197 bool SurfaceCollection::evaluateAnimations(double currentTime)
    198 {
    199     return m_compositedRoot->evaluateAnimations(currentTime);
    200 }
    201 
    202 bool SurfaceCollection::hasCompositedLayers()
    203 {
    204     return m_compositedRoot->countChildren();
    205 }
    206 
    207 bool SurfaceCollection::hasCompositedAnimations()
    208 {
    209     return m_compositedRoot->hasAnimations();
    210 }
    211 
    212 void SurfaceCollection::updateScrollableLayer(int layerId, int x, int y)
    213 {
    214     LayerAndroid* layer = m_compositedRoot->findById(layerId);
    215     if (layer && layer->contentIsScrollable())
    216         static_cast<ScrollableLayerAndroid*>(layer)->scrollTo(x, y);
    217 }
    218 
    219 void SurfaceCollection::updateLayerPositions(const SkRect& visibleContentRect)
    220 {
    221     m_compositedRoot->updatePositionsRecursive(visibleContentRect);
    222 
    223 #ifdef DEBUG
    224     m_compositedRoot->showLayer(0);
    225     ALOGV("We have %d layers, %d textured",
    226           m_compositedRoot->nbLayers(),
    227           m_compositedRoot->nbTexturedLayers());
    228 #endif
    229 }
    230 
    231 int SurfaceCollection::backedSize()
    232 {
    233     int count = 0;
    234     for (unsigned int i = 0; i < m_surfaces.size(); i++) {
    235         if (m_surfaces[i]->needsTexture())
    236             count++;
    237     }
    238     return count;
    239 }
    240 
    241 } // namespace WebCore
    242