LCOV - app.info - gfx/layers/opengl/ContainerLayerOGL.cpp

LCOV - code coverage report
| Current view: | directory - gfx/layers/opengl - ContainerLayerOGL.cpp (source / functions) |  | Found | Hit | Coverage |
| Test: | app.info | Lines: | 188 | 0 | 0.0 %
| Date: | 2012-07-07 | Functions: | 29 | 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) 2009
          19                 :  * the Initial Developer. All Rights Reserved.
          20                 :  *
          21                 :  * Contributor(s):
          22                 :  *   Bas Schouten <bschouten@mozilla.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 "ContainerLayerOGL.h"
          39                 : #include "gfxUtils.h"
          40                 :
          41                 : namespace mozilla {
          42                 : namespace layers {
          43                 :
          44                 : template<class Container>
          45                 : static void
          46               0 : ContainerInsertAfter(Container* aContainer, Layer* aChild, Layer* aAfter)
          47                 : {
          48               0 :   aChild->SetParent(aContainer);
          49               0 :   if (!aAfter) {
          50               0 :     Layer *oldFirstChild = aContainer->GetFirstChild();
          51               0 :     aContainer->mFirstChild = aChild;
          52               0 :     aChild->SetNextSibling(oldFirstChild);
          53               0 :     aChild->SetPrevSibling(nsnull);
          54               0 :     if (oldFirstChild) {
          55               0 :       oldFirstChild->SetPrevSibling(aChild);
          56                 :     } else {
          57               0 :       aContainer->mLastChild = aChild;
          58                 :     }
          59               0 :     NS_ADDREF(aChild);
          60               0 :     aContainer->DidInsertChild(aChild);
          61               0 :     return;
          62                 :   }
          63               0 :   for (Layer *child = aContainer->GetFirstChild();
          64                 :        child; child = child->GetNextSibling()) {
          65               0 :     if (aAfter == child) {
          66               0 :       Layer *oldNextSibling = child->GetNextSibling();
          67               0 :       child->SetNextSibling(aChild);
          68               0 :       aChild->SetNextSibling(oldNextSibling);
          69               0 :       if (oldNextSibling) {
          70               0 :         oldNextSibling->SetPrevSibling(aChild);
          71                 :       } else {
          72               0 :         aContainer->mLastChild = aChild;
          73                 :       }
          74               0 :       aChild->SetPrevSibling(child);
          75               0 :       NS_ADDREF(aChild);
          76               0 :       aContainer->DidInsertChild(aChild);
          77               0 :       return;
          78                 :     }
          79                 :   }
          80               0 :   NS_WARNING("Failed to find aAfter layer!");
          81                 : }
          82                 :
          83                 : template<class Container>
          84                 : static void
          85               0 : ContainerRemoveChild(Container* aContainer, Layer* aChild)
          86                 : {
          87               0 :   if (aContainer->GetFirstChild() == aChild) {
          88               0 :     aContainer->mFirstChild = aContainer->GetFirstChild()->GetNextSibling();
          89               0 :     if (aContainer->mFirstChild) {
          90               0 :       aContainer->mFirstChild->SetPrevSibling(nsnull);
          91                 :     } else {
          92               0 :       aContainer->mLastChild = nsnull;
          93                 :     }
          94               0 :     aChild->SetNextSibling(nsnull);
          95               0 :     aChild->SetPrevSibling(nsnull);
          96               0 :     aChild->SetParent(nsnull);
          97               0 :     aContainer->DidRemoveChild(aChild);
          98               0 :     NS_RELEASE(aChild);
          99               0 :     return;
         100                 :   }
         101               0 :   Layer *lastChild = nsnull;
         102               0 :   for (Layer *child = aContainer->GetFirstChild(); child;
         103                 :        child = child->GetNextSibling()) {
         104               0 :     if (child == aChild) {
         105                 :       // We're sure this is not our first child. So lastChild != NULL.
         106               0 :       lastChild->SetNextSibling(child->GetNextSibling());
         107               0 :       if (child->GetNextSibling()) {
         108               0 :         child->GetNextSibling()->SetPrevSibling(lastChild);
         109                 :       } else {
         110               0 :         aContainer->mLastChild = lastChild;
         111                 :       }
         112               0 :       child->SetNextSibling(nsnull);
         113               0 :       child->SetPrevSibling(nsnull);
         114               0 :       child->SetParent(nsnull);
         115               0 :       aContainer->DidRemoveChild(aChild);
         116               0 :       NS_RELEASE(aChild);
         117               0 :       return;
         118                 :     }
         119               0 :     lastChild = child;
         120                 :   }
         121                 : }
         122                 :
         123                 : template<class Container>
         124                 : static void
         125               0 : ContainerDestroy(Container* aContainer)
         126                 :  {
         127               0 :   if (!aContainer->mDestroyed) {
         128               0 :     while (aContainer->mFirstChild) {
         129               0 :       aContainer->GetFirstChildOGL()->Destroy();
         130               0 :       aContainer->RemoveChild(aContainer->mFirstChild);
         131                 :     }
         132               0 :     aContainer->mDestroyed = true;
         133                 :   }
         134               0 : }
         135                 :
         136                 : template<class Container>
         137                 : static void
         138               0 : ContainerCleanupResources(Container* aContainer)
         139                 : {
         140               0 :   for (Layer* l = aContainer->GetFirstChild(); l; l = l->GetNextSibling()) {
         141               0 :     LayerOGL* layerToRender = static_cast<LayerOGL*>(l->ImplData());
         142               0 :     layerToRender->CleanupResources();
         143                 :   }
         144               0 : }
         145                 :
         146                 : static inline LayerOGL*
         147                 : GetNextSibling(LayerOGL* aLayer)
         148                 : {
         149                 :    Layer* layer = aLayer->GetLayer()->GetNextSibling();
         150                 :    return layer ? static_cast<LayerOGL*>(layer->
         151                 :                                          ImplData())
         152                 :                  : nsnull;
         153                 : }
         154                 :
         155                 : static bool
         156               0 : HasOpaqueAncestorLayer(Layer* aLayer)
         157                 : {
         158               0 :   for (Layer* l = aLayer->GetParent(); l; l = l->GetParent()) {
         159               0 :     if (l->GetContentFlags() & Layer::CONTENT_OPAQUE)
         160               0 :       return true;
         161                 :   }
         162               0 :   return false;
         163                 : }
         164                 :
         165                 : template<class Container>
         166                 : static void
         167                 : ContainerRender(Container* aContainer,
         168                 :                 int aPreviousFrameBuffer,
         169                 :                 const nsIntPoint& aOffset,
         170               0 :                 LayerManagerOGL* aManager)
         171                 : {
         172                 :   /**
         173                 :    * Setup our temporary texture for rendering the contents of this container.
         174                 :    */
         175                 :   GLuint containerSurface;
         176                 :   GLuint frameBuffer;
         177                 :
         178               0 :   nsIntPoint childOffset(aOffset);
         179               0 :   nsIntRect visibleRect = aContainer->GetEffectiveVisibleRegion().GetBounds();
         180                 :
         181               0 :   nsIntRect cachedScissor = aContainer->gl()->ScissorRect();
         182               0 :   aContainer->gl()->PushScissorRect();
         183               0 :   aContainer->mSupportsComponentAlphaChildren = false;
         184                 :
         185               0 :   float opacity = aContainer->GetEffectiveOpacity();
         186               0 :   const gfx3DMatrix& transform = aContainer->GetEffectiveTransform();
         187               0 :   bool needsFramebuffer = aContainer->UseIntermediateSurface();
         188               0 :   if (needsFramebuffer) {
         189               0 :     LayerManagerOGL::InitMode mode = LayerManagerOGL::InitModeClear;
         190               0 :     nsIntRect framebufferRect = visibleRect;
         191               0 :     if (aContainer->GetEffectiveVisibleRegion().GetNumRects() == 1 &&
         192                 :         (aContainer->GetContentFlags() & Layer::CONTENT_OPAQUE))
         193                 :     {
         194                 :       // don't need a background, we're going to paint all opaque stuff
         195               0 :       aContainer->mSupportsComponentAlphaChildren = true;
         196               0 :       mode = LayerManagerOGL::InitModeNone;
         197                 :     } else {
         198               0 :       const gfx3DMatrix& transform3D = aContainer->GetEffectiveTransform();
         199               0 :       gfxMatrix transform;
         200                 :       // If we have an opaque ancestor layer, then we can be sure that
         201                 :       // all the pixels we draw into are either opaque already or will be
         202                 :       // covered by something opaque. Otherwise copying up the background is
         203                 :       // not safe.
         204               0 :       if (HasOpaqueAncestorLayer(aContainer) &&
         205                 :           transform3D.Is2D(&transform) && !transform.HasNonIntegerTranslation()) {
         206               0 :         mode = LayerManagerOGL::InitModeCopy;
         207               0 :         framebufferRect.x += transform.x0;
         208               0 :         framebufferRect.y += transform.y0;
         209               0 :         aContainer->mSupportsComponentAlphaChildren = true;
         210                 :       }
         211                 :     }
         212                 :
         213               0 :     aContainer->gl()->PushViewportRect();
         214               0 :     framebufferRect -= childOffset;
         215               0 :     aManager->CreateFBOWithTexture(framebufferRect,
         216                 :                                    mode,
         217                 :                                    aPreviousFrameBuffer,
         218                 :                                    &frameBuffer,
         219                 :                                    &containerSurface);
         220               0 :     childOffset.x = visibleRect.x;
         221               0 :     childOffset.y = visibleRect.y;
         222                 :   } else {
         223               0 :     frameBuffer = aPreviousFrameBuffer;
         224               0 :     aContainer->mSupportsComponentAlphaChildren = (aContainer->GetContentFlags() & Layer::CONTENT_OPAQUE) ||
         225                 :       (aContainer->GetParent() && aContainer->GetParent()->SupportsComponentAlphaChildren());
         226                 :   }
         227                 :
         228               0 :   nsAutoTArray<Layer*, 12> children;
         229               0 :   aContainer->SortChildrenBy3DZOrder(children);
         230                 :
         231                 :   /**
         232                 :    * Render this container's contents.
         233                 :    */
         234               0 :   for (PRUint32 i = 0; i < children.Length(); i++) {
         235               0 :     LayerOGL* layerToRender = static_cast<LayerOGL*>(children.ElementAt(i)->ImplData());
         236                 :
         237               0 :     if (layerToRender->GetLayer()->GetEffectiveVisibleRegion().IsEmpty()) {
         238               0 :       continue;
         239                 :     }
         240                 :
         241                 :     nsIntRect scissorRect = layerToRender->GetLayer()->
         242               0 :         CalculateScissorRect(cachedScissor, &aManager->GetWorldTransform());
         243               0 :     if (scissorRect.IsEmpty()) {
         244               0 :       continue;
         245                 :     }
         246                 :
         247               0 :     aContainer->gl()->fScissor(scissorRect.x,
         248                 :                                scissorRect.y,
         249                 :                                scissorRect.width,
         250                 :                                scissorRect.height);
         251                 :
         252               0 :     layerToRender->RenderLayer(frameBuffer, childOffset);
         253               0 :     aContainer->gl()->MakeCurrent();
         254                 :   }
         255                 :
         256                 :
         257               0 :   if (needsFramebuffer) {
         258                 :     // Unbind the current framebuffer and rebind the previous one.
         259                 : #ifdef MOZ_DUMP_PAINTING
         260               0 :     if (gfxUtils::sDumpPainting) {
         261                 :       nsRefPtr<gfxImageSurface> surf =
         262               0 :         aContainer->gl()->GetTexImage(containerSurface, true, aManager->GetFBOLayerProgramType());
         263                 :
         264               0 :       WriteSnapshotToDumpFile(aContainer, surf);
         265                 :     }
         266                 : #endif
         267                 :
         268                 :     // Restore the viewport
         269               0 :     aContainer->gl()->PopViewportRect();
         270               0 :     nsIntRect viewport = aContainer->gl()->ViewportRect();
         271               0 :     aManager->SetupPipeline(viewport.width, viewport.height,
         272                 :                             LayerManagerOGL::ApplyWorldTransform);
         273               0 :     aContainer->gl()->PopScissorRect();
         274                 :
         275               0 :     aContainer->gl()->fBindFramebuffer(LOCAL_GL_FRAMEBUFFER, aPreviousFrameBuffer);
         276               0 :     aContainer->gl()->fDeleteFramebuffers(1, &frameBuffer);
         277                 :
         278               0 :     aContainer->gl()->fActiveTexture(LOCAL_GL_TEXTURE0);
         279                 :
         280               0 :     aContainer->gl()->fBindTexture(aManager->FBOTextureTarget(), containerSurface);
         281                 :
         282               0 :     ColorTextureLayerProgram *rgb = aManager->GetFBOLayerProgram();
         283                 :
         284               0 :     rgb->Activate();
         285               0 :     rgb->SetLayerQuadRect(visibleRect);
         286               0 :     rgb->SetLayerTransform(transform);
         287               0 :     rgb->SetLayerOpacity(opacity);
         288               0 :     rgb->SetRenderOffset(aOffset);
         289               0 :     rgb->SetTextureUnit(0);
         290                 :
         291               0 :     if (rgb->GetTexCoordMultiplierUniformLocation() != -1) {
         292                 :       // 2DRect case, get the multiplier right for a sampler2DRect
         293               0 :       float f[] = { float(visibleRect.width), float(visibleRect.height) };
         294               0 :       rgb->SetUniform(rgb->GetTexCoordMultiplierUniformLocation(),
         295                 :                       2, f);
         296                 :     }
         297                 :
         298                 :     // Drawing is always flipped, but when copying between surfaces we want to avoid
         299                 :     // this. Pass true for the flip parameter to introduce a second flip
         300                 :     // that cancels the other one out.
         301               0 :     aManager->BindAndDrawQuad(rgb, true);
         302                 :
         303                 :     // Clean up resources.  This also unbinds the texture.
         304               0 :     aContainer->gl()->fDeleteTextures(1, &containerSurface);
         305                 :   } else {
         306               0 :     aContainer->gl()->PopScissorRect();
         307                 :   }
         308               0 : }
         309                 :
         310               0 : ContainerLayerOGL::ContainerLayerOGL(LayerManagerOGL *aManager)
         311                 :   : ContainerLayer(aManager, NULL)
         312               0 :   , LayerOGL(aManager)
         313                 : {
         314               0 :   mImplData = static_cast<LayerOGL*>(this);
         315               0 : }
         316                 :
         317               0 : ContainerLayerOGL::~ContainerLayerOGL()
         318                 : {
         319               0 :   Destroy();
         320               0 : }
         321                 :
         322                 : void
         323               0 : ContainerLayerOGL::InsertAfter(Layer* aChild, Layer* aAfter)
         324                 : {
         325               0 :   ContainerInsertAfter(this, aChild, aAfter);
         326               0 : }
         327                 :
         328                 : void
         329               0 : ContainerLayerOGL::RemoveChild(Layer *aChild)
         330                 : {
         331               0 :   ContainerRemoveChild(this, aChild);
         332               0 : }
         333                 :
         334                 : void
         335               0 : ContainerLayerOGL::Destroy()
         336                 : {
         337               0 :   ContainerDestroy(this);
         338               0 : }
         339                 :
         340                 : LayerOGL*
         341               0 : ContainerLayerOGL::GetFirstChildOGL()
         342                 : {
         343               0 :   if (!mFirstChild) {
         344               0 :     return nsnull;
         345                 :   }
         346               0 :   return static_cast<LayerOGL*>(mFirstChild->ImplData());
         347                 : }
         348                 :
         349                 : void
         350               0 : ContainerLayerOGL::RenderLayer(int aPreviousFrameBuffer,
         351                 :                                const nsIntPoint& aOffset)
         352                 : {
         353               0 :   ContainerRender(this, aPreviousFrameBuffer, aOffset, mOGLManager);
         354               0 : }
         355                 :
         356                 : void
         357               0 : ContainerLayerOGL::CleanupResources()
         358                 : {
         359               0 :   ContainerCleanupResources(this);
         360               0 : }
         361                 :
         362               0 : ShadowContainerLayerOGL::ShadowContainerLayerOGL(LayerManagerOGL *aManager)
         363                 :   : ShadowContainerLayer(aManager, NULL)
         364               0 :   , LayerOGL(aManager)
         365                 : {
         366               0 :   mImplData = static_cast<LayerOGL*>(this);
         367               0 : }
         368                 :
         369               0 : ShadowContainerLayerOGL::~ShadowContainerLayerOGL()
         370                 : {
         371               0 :   Destroy();
         372               0 : }
         373                 :
         374                 : void
         375               0 : ShadowContainerLayerOGL::InsertAfter(Layer* aChild, Layer* aAfter)
         376                 : {
         377               0 :   ContainerInsertAfter(this, aChild, aAfter);
         378               0 : }
         379                 :
         380                 : void
         381               0 : ShadowContainerLayerOGL::RemoveChild(Layer *aChild)
         382                 : {
         383               0 :   ContainerRemoveChild(this, aChild);
         384               0 : }
         385                 :
         386                 : void
         387               0 : ShadowContainerLayerOGL::Destroy()
         388                 : {
         389               0 :   ContainerDestroy(this);
         390               0 : }
         391                 :
         392                 : LayerOGL*
         393               0 : ShadowContainerLayerOGL::GetFirstChildOGL()
         394                 : {
         395               0 :   if (!mFirstChild) {
         396               0 :     return nsnull;
         397                 :    }
         398               0 :   return static_cast<LayerOGL*>(mFirstChild->ImplData());
         399                 : }
         400                 :
         401                 : void
         402               0 : ShadowContainerLayerOGL::RenderLayer(int aPreviousFrameBuffer,
         403                 :                                      const nsIntPoint& aOffset)
         404                 : {
         405               0 :   ContainerRender(this, aPreviousFrameBuffer, aOffset, mOGLManager);
         406               0 : }
         407                 :
         408                 : void
         409               0 : ShadowContainerLayerOGL::CleanupResources()
         410                 : {
         411               0 :   ContainerCleanupResources(this);
         412               0 : }
         413                 :
         414                 : } /* layers */
         415                 : } /* mozilla */

Generated by: LCOV version 1.7