LCOV - app.info - gfx/layers/ReadbackProcessor.cpp

LCOV - code coverage report
| Current view: | directory - gfx/layers - ReadbackProcessor.cpp (source / functions) |  | Found | Hit | Coverage |
| Test: | app.info | Lines: | 94 | 0 | 0.0 %
| Date: | 2012-07-07 | Functions: | 5 | 0 | 0.0 %

           1                 : /* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*-
           2                 :  * ***** BEGIN LICENSE BLOCK *****
           3                 :  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
           4                 :  *
           5                 :  * The contents of this file are subject to the Mozilla Public License Version
           6                 :  * 1.1 (the "License"); you may not use this file except in compliance with
           7                 :  * the License. You may obtain a copy of the License at
           8                 :  * http://www.mozilla.org/MPL/
           9                 :  *
          10                 :  * Software distributed under the License is distributed on an "AS IS" basis,
          11                 :  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
          12                 :  * for the specific language governing rights and limitations under the
          13                 :  * License.
          14                 :  *
          15                 :  * The Original Code is Mozilla Corporation code.
          16                 :  *
          17                 :  * The Initial Developer of the Original Code is Mozilla Foundation.
          18                 :  * Portions created by the Initial Developer are Copyright (C) 2011
          19                 :  * the Initial Developer. All Rights Reserved.
          20                 :  *
          21                 :  * Contributor(s):
          22                 :  *   Robert O'Callahan <robert@ocallahan.org>
          23                 :  *
          24                 :  * Alternatively, the contents of this file may be used under the terms of
          25                 :  * either the GNU General Public License Version 2 or later (the "GPL"), or
          26                 :  * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
          27                 :  * in which case the provisions of the GPL or the LGPL are applicable instead
          28                 :  * of those above. If you wish to allow use of your version of this file only
          29                 :  * under the terms of either the GPL or the LGPL, and not to allow others to
          30                 :  * use your version of this file under the terms of the MPL, indicate your
          31                 :  * decision by deleting the provisions above and replace them with the notice
          32                 :  * and other provisions required by the GPL or the LGPL. If you do not delete
          33                 :  * the provisions above, a recipient may use your version of this file under
          34                 :  * the terms of any one of the MPL, the GPL or the LGPL.
          35                 :  *
          36                 :  * ***** END LICENSE BLOCK ***** */
          37                 :
          38                 : #include "ReadbackProcessor.h"
          39                 :
          40                 : namespace mozilla {
          41                 : namespace layers {
          42                 :
          43                 : void
          44               0 : ReadbackProcessor::BuildUpdates(ContainerLayer* aContainer)
          45                 : {
          46               0 :   NS_ASSERTION(mAllUpdates.IsEmpty(), "Some updates not processed?");
          47                 :
          48               0 :   if (!aContainer->mMayHaveReadbackChild)
          49               0 :     return;
          50                 :
          51               0 :   aContainer->mMayHaveReadbackChild = false;
          52                 :   // go backwards so the updates read from earlier layers are later in the
          53                 :   // array.
          54               0 :   for (Layer* l = aContainer->GetLastChild(); l; l = l->GetPrevSibling()) {
          55               0 :     if (l->GetType() == Layer::TYPE_READBACK) {
          56               0 :       aContainer->mMayHaveReadbackChild = true;
          57               0 :       BuildUpdatesForLayer(static_cast<ReadbackLayer*>(l));
          58                 :     }
          59                 :   }
          60                 : }
          61                 :
          62                 : static Layer*
          63               0 : FindBackgroundLayer(ReadbackLayer* aLayer, nsIntPoint* aOffset)
          64                 : {
          65               0 :   gfxMatrix transform;
          66               0 :   if (!aLayer->GetTransform().Is2D(&transform) ||
          67               0 :       transform.HasNonIntegerTranslation())
          68               0 :     return nsnull;
          69               0 :   nsIntPoint transformOffset(PRInt32(transform.x0), PRInt32(transform.y0));
          70                 :
          71               0 :   for (Layer* l = aLayer->GetPrevSibling(); l; l = l->GetPrevSibling()) {
          72               0 :     gfxMatrix backgroundTransform;
          73               0 :     if (!l->GetTransform().Is2D(&backgroundTransform) ||
          74               0 :         backgroundTransform.HasNonIntegerTranslation())
          75               0 :       return nsnull;
          76                 :
          77               0 :     nsIntPoint backgroundOffset(PRInt32(backgroundTransform.x0), PRInt32(backgroundTransform.y0));
          78               0 :     nsIntRect rectInBackground(transformOffset - backgroundOffset, aLayer->GetSize());
          79               0 :     const nsIntRegion& visibleRegion = l->GetEffectiveVisibleRegion();
          80               0 :     if (!visibleRegion.Intersects(rectInBackground))
          81               0 :       continue;
          82                 :     // Since l is present in the background, from here on we either choose l
          83                 :     // or nothing.
          84               0 :     if (!visibleRegion.Contains(rectInBackground))
          85               0 :       return nsnull;
          86                 :
          87               0 :     if (l->GetEffectiveOpacity() != 1.0 ||
          88               0 :         !(l->GetContentFlags() & Layer::CONTENT_OPAQUE))
          89               0 :       return nsnull;
          90                 :
          91                 :     // cliprects are post-transform
          92               0 :     const nsIntRect* clipRect = l->GetEffectiveClipRect();
          93               0 :     if (clipRect && !clipRect->Contains(nsIntRect(transformOffset, aLayer->GetSize())))
          94               0 :       return nsnull;
          95                 :
          96               0 :     Layer::LayerType type = l->GetType();
          97               0 :     if (type != Layer::TYPE_COLOR && type != Layer::TYPE_THEBES)
          98               0 :       return nsnull;
          99                 :
         100               0 :     *aOffset = backgroundOffset - transformOffset;
         101               0 :     return l;
         102                 :   }
         103                 :
         104               0 :   return nsnull;
         105                 : }
         106                 :
         107                 : void
         108               0 : ReadbackProcessor::BuildUpdatesForLayer(ReadbackLayer* aLayer)
         109                 : {
         110               0 :   if (!aLayer->mSink)
         111               0 :     return;
         112                 :
         113               0 :   nsIntPoint offset;
         114               0 :   Layer* newBackground = FindBackgroundLayer(aLayer, &offset);
         115               0 :   if (!newBackground) {
         116               0 :     aLayer->SetUnknown();
         117               0 :     return;
         118                 :   }
         119                 :
         120               0 :   if (newBackground->GetType() == Layer::TYPE_COLOR) {
         121               0 :     ColorLayer* colorLayer = static_cast<ColorLayer*>(newBackground);
         122               0 :     if (aLayer->mBackgroundColor != colorLayer->GetColor()) {
         123               0 :       aLayer->mBackgroundLayer = nsnull;
         124               0 :       aLayer->mBackgroundColor = colorLayer->GetColor();
         125               0 :       NS_ASSERTION(aLayer->mBackgroundColor.a == 1.0,
         126                 :                    "Color layer said it was opaque!");
         127                 :       nsRefPtr<gfxContext> ctx =
         128               0 :           aLayer->mSink->BeginUpdate(aLayer->GetRect(),
         129               0 :                                      aLayer->AllocateSequenceNumber());
         130               0 :       if (ctx) {
         131               0 :         ctx->SetColor(aLayer->mBackgroundColor);
         132               0 :         nsIntSize size = aLayer->GetSize();
         133               0 :         ctx->Rectangle(gfxRect(0, 0, size.width, size.height));
         134               0 :         ctx->Fill();
         135               0 :         aLayer->mSink->EndUpdate(ctx, aLayer->GetRect());
         136                 :       }
         137                 :     }
         138                 :   } else {
         139               0 :     NS_ASSERTION(newBackground->AsThebesLayer(), "Must be ThebesLayer");
         140               0 :     ThebesLayer* thebesLayer = static_cast<ThebesLayer*>(newBackground);
         141                 :     // updateRect is relative to the ThebesLayer
         142               0 :     nsIntRect updateRect = aLayer->GetRect() - offset;
         143               0 :     if (thebesLayer != aLayer->mBackgroundLayer ||
         144               0 :         offset != aLayer->mBackgroundLayerOffset) {
         145               0 :       aLayer->mBackgroundLayer = thebesLayer;
         146               0 :       aLayer->mBackgroundLayerOffset = offset;
         147               0 :       aLayer->mBackgroundColor = gfxRGBA(0,0,0,0);
         148               0 :       thebesLayer->SetUsedForReadback(true);
         149                 :     } else {
         150               0 :       nsIntRegion invalid;
         151               0 :       invalid.Sub(updateRect, thebesLayer->GetValidRegion());
         152               0 :       updateRect = invalid.GetBounds();
         153                 :     }
         154                 :
         155               0 :     Update update = { aLayer, updateRect, aLayer->AllocateSequenceNumber() };
         156               0 :     mAllUpdates.AppendElement(update);
         157                 :   }
         158                 : }
         159                 :
         160                 : void
         161               0 : ReadbackProcessor::GetThebesLayerUpdates(ThebesLayer* aLayer,
         162                 :                                          nsTArray<Update>* aUpdates,
         163                 :                                          nsIntRegion* aUpdateRegion)
         164                 : {
         165                 :   // All ThebesLayers used for readback are in mAllUpdates (some possibly
         166                 :   // with an empty update rect).
         167               0 :   aLayer->SetUsedForReadback(false);
         168               0 :   if (aUpdateRegion) {
         169               0 :     aUpdateRegion->SetEmpty();
         170                 :   }
         171               0 :   for (PRUint32 i = mAllUpdates.Length(); i > 0; --i) {
         172               0 :     const Update& update = mAllUpdates[i - 1];
         173               0 :     if (update.mLayer->mBackgroundLayer == aLayer) {
         174               0 :       aLayer->SetUsedForReadback(true);
         175                 :       // Don't bother asking for updates if we have an empty update rect.
         176               0 :       if (!update.mUpdateRect.IsEmpty()) {
         177               0 :         aUpdates->AppendElement(update);
         178               0 :         if (aUpdateRegion) {
         179               0 :           aUpdateRegion->Or(*aUpdateRegion, update.mUpdateRect);
         180                 :         }
         181                 :       }
         182               0 :       mAllUpdates.RemoveElementAt(i - 1);
         183                 :     }
         184                 :   }
         185               0 : }
         186                 :
         187               0 : ReadbackProcessor::~ReadbackProcessor()
         188                 : {
         189               0 :   for (PRUint32 i = mAllUpdates.Length(); i > 0; --i) {
         190               0 :     const Update& update = mAllUpdates[i - 1];
         191                 :     // Unprocessed update. Notify the readback sink that this content is
         192                 :     // unknown.
         193               0 :     update.mLayer->SetUnknown();
         194                 :   }
         195               0 : }
         196                 :
         197                 : }
         198                 : }

Generated by: LCOV version 1.7