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

LCOV - code coverage report
| Current view: | directory - gfx/layers/opengl - CanvasLayerOGL.cpp (source / functions) |  | Found | Hit | Coverage |
| Test: | app.info | Lines: | 178 | 0 | 0.0 %
| Date: | 2012-04-21 | Functions: | 18 | 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) 2010
          19                 :  * the Initial Developer. All Rights Reserved.
          20                 :  *
          21                 :  * Contributor(s):
          22                 :  *   Vladimir Vukicevic <vladimir@pobox.com>
          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 "mozilla/layers/PLayers.h"
          39                 : #include "mozilla/layers/ShadowLayers.h"
          40                 :
          41                 : #include "gfxSharedImageSurface.h"
          42                 :
          43                 : #include "CanvasLayerOGL.h"
          44                 :
          45                 : #include "gfxImageSurface.h"
          46                 : #include "gfxContext.h"
          47                 : #include "GLContextProvider.h"
          48                 : #include "gfxPlatform.h"
          49                 :
          50                 : #ifdef XP_WIN
          51                 : #include "gfxWindowsSurface.h"
          52                 : #include "WGLLibrary.h"
          53                 : #endif
          54                 :
          55                 : #ifdef XP_MACOSX
          56                 : #include <OpenGL/OpenGL.h>
          57                 : #endif
          58                 :
          59                 : #ifdef MOZ_X11
          60                 : #include "gfxXlibSurface.h"
          61                 : #endif
          62                 :
          63                 : using namespace mozilla;
          64                 : using namespace mozilla::layers;
          65                 : using namespace mozilla::gl;
          66                 :
          67                 : void
          68               0 : CanvasLayerOGL::Destroy()
          69                 : {
          70               0 :   if (!mDestroyed) {
          71               0 :     CleanupResources();
          72               0 :     mDestroyed = true;
          73                 :   }
          74               0 : }
          75                 :
          76                 : void
          77               0 : CanvasLayerOGL::Initialize(const Data& aData)
          78                 : {
          79               0 :   NS_ASSERTION(mCanvasSurface == nsnull, "BasicCanvasLayer::Initialize called twice!");
          80                 :
          81               0 :   if (aData.mGLContext != nsnull &&
          82                 :       aData.mSurface != nsnull)
          83                 :   {
          84               0 :     NS_WARNING("CanvasLayerOGL can't have both surface and GLContext");
          85               0 :     return;
          86                 :   }
          87                 :
          88               0 :   mOGLManager->MakeCurrent();
          89                 :
          90               0 :   if (aData.mDrawTarget) {
          91               0 :     mDrawTarget = aData.mDrawTarget;
          92               0 :     mNeedsYFlip = false;
          93               0 :   } else if (aData.mSurface) {
          94               0 :     mCanvasSurface = aData.mSurface;
          95               0 :     mNeedsYFlip = false;
          96                 : #if defined(MOZ_WIDGET_GTK2) && !defined(MOZ_PLATFORM_MAEMO)
          97               0 :     if (aData.mSurface->GetType() == gfxASurface::SurfaceTypeXlib) {
          98               0 :         gfxXlibSurface *xsurf = static_cast<gfxXlibSurface*>(aData.mSurface);
          99               0 :         mPixmap = xsurf->GetGLXPixmap();
         100               0 :         if (mPixmap) {
         101               0 :             if (aData.mSurface->GetContentType() == gfxASurface::CONTENT_COLOR_ALPHA) {
         102               0 :                 mLayerProgram = gl::RGBALayerProgramType;
         103                 :             } else {
         104               0 :                 mLayerProgram = gl::RGBXLayerProgramType;
         105                 :             }
         106               0 :             MakeTexture();
         107                 :         }
         108                 :     }
         109                 : #endif
         110               0 :   } else if (aData.mGLContext) {
         111               0 :     if (!aData.mGLContext->IsOffscreen()) {
         112               0 :       NS_WARNING("CanvasLayerOGL with a non-offscreen GL context given");
         113               0 :       return;
         114                 :     }
         115                 :
         116               0 :     mCanvasGLContext = aData.mGLContext;
         117               0 :     mGLBufferIsPremultiplied = aData.mGLBufferIsPremultiplied;
         118                 :
         119               0 :     mNeedsYFlip = true;
         120                 :   } else {
         121               0 :     NS_WARNING("CanvasLayerOGL::Initialize called without surface or GL context!");
         122               0 :     return;
         123                 :   }
         124                 :
         125               0 :   mBounds.SetRect(0, 0, aData.mSize.width, aData.mSize.height);
         126                 :
         127                 :   // Check the maximum texture size supported by GL. glTexImage2D supports
         128                 :   // images of up to 2 + GL_MAX_TEXTURE_SIZE
         129               0 :   GLint texSize = gl()->GetMaxTextureSize();
         130               0 :   if (mBounds.width > (2 + texSize) || mBounds.height > (2 + texSize)) {
         131               0 :     mDelayedUpdates = true;
         132               0 :     MakeTexture();
         133                 :     // This should only ever occur with 2d canvas, WebGL can't already have a texture
         134                 :     // of this size can it?
         135               0 :     NS_ABORT_IF_FALSE(mCanvasSurface || mDrawTarget,
         136                 :                       "Invalid texture size when WebGL surface already exists at that size?");
         137                 :   }
         138                 : }
         139                 :
         140                 : void
         141               0 : CanvasLayerOGL::MakeTexture()
         142                 : {
         143               0 :   if (mTexture != 0)
         144               0 :     return;
         145                 :
         146               0 :   gl()->fGenTextures(1, &mTexture);
         147                 :
         148               0 :   gl()->fActiveTexture(LOCAL_GL_TEXTURE0);
         149               0 :   gl()->fBindTexture(LOCAL_GL_TEXTURE_2D, mTexture);
         150                 :
         151               0 :   gl()->fTexParameteri(LOCAL_GL_TEXTURE_2D, LOCAL_GL_TEXTURE_MIN_FILTER, LOCAL_GL_LINEAR);
         152               0 :   gl()->fTexParameteri(LOCAL_GL_TEXTURE_2D, LOCAL_GL_TEXTURE_MAG_FILTER, LOCAL_GL_LINEAR);
         153               0 :   gl()->fTexParameteri(LOCAL_GL_TEXTURE_2D, LOCAL_GL_TEXTURE_WRAP_S, LOCAL_GL_CLAMP_TO_EDGE);
         154               0 :   gl()->fTexParameteri(LOCAL_GL_TEXTURE_2D, LOCAL_GL_TEXTURE_WRAP_T, LOCAL_GL_CLAMP_TO_EDGE);
         155                 : }
         156                 :
         157                 : /**
         158                 :  * Following UpdateSurface(), mTexture on context this->gl() should contain the data we want,
         159                 :  * unless mDelayedUpdates is true because of a too-large surface.
         160                 :  */
         161                 : void
         162               0 : CanvasLayerOGL::UpdateSurface()
         163                 : {
         164               0 :   if (!mDirty)
         165               0 :     return;
         166               0 :   mDirty = false;
         167                 :
         168               0 :   if (mDestroyed || mDelayedUpdates) {
         169               0 :     return;
         170                 :   }
         171                 :
         172                 : #if defined(MOZ_WIDGET_GTK2) && !defined(MOZ_PLATFORM_MAEMO)
         173               0 :   if (mPixmap) {
         174               0 :     return;
         175                 :   }
         176                 : #endif
         177                 :
         178               0 :   if (mCanvasGLContext &&
         179               0 :       mCanvasGLContext->GetContextType() == gl()->GetContextType())
         180                 :   {
         181                 :     // Can texture share, just make sure it's resolved first
         182               0 :     mCanvasGLContext->MakeCurrent();
         183               0 :     mCanvasGLContext->GuaranteeResolve();
         184                 :
         185               0 :     if (gl()->BindOffscreenNeedsTexture(mCanvasGLContext) &&
         186                 :         mTexture == 0)
         187                 :     {
         188               0 :       mOGLManager->MakeCurrent();
         189               0 :       MakeTexture();
         190                 :     }
         191                 :   } else {
         192               0 :     nsRefPtr<gfxASurface> updatedAreaSurface;
         193               0 :     if (mDrawTarget) {
         194                 :       // TODO: This is suboptimal - We should have direct handling for the surface types instead of
         195                 :       // going via a gfxASurface.
         196               0 :       updatedAreaSurface = gfxPlatform::GetPlatform()->GetThebesSurfaceForDrawTarget(mDrawTarget);
         197               0 :     } else if (mCanvasSurface) {
         198               0 :       updatedAreaSurface = mCanvasSurface;
         199               0 :     } else if (mCanvasGLContext) {
         200                 :       nsRefPtr<gfxImageSurface> updatedAreaImageSurface =
         201                 :         new gfxImageSurface(gfxIntSize(mBounds.width, mBounds.height),
         202               0 :                             gfxASurface::ImageFormatARGB32);
         203                 :       mCanvasGLContext->ReadPixelsIntoImageSurface(0, 0,
         204                 :                                                    mBounds.width,
         205                 :                                                    mBounds.height,
         206               0 :                                                    updatedAreaImageSurface);
         207               0 :       updatedAreaSurface = updatedAreaImageSurface;
         208                 :     }
         209                 :
         210               0 :     mOGLManager->MakeCurrent();
         211                 :     mLayerProgram =
         212                 :       gl()->UploadSurfaceToTexture(updatedAreaSurface,
         213                 :                                    mBounds,
         214                 :                                    mTexture,
         215                 :                                    false,
         216               0 :                                    nsIntPoint(0, 0));
         217                 :   }
         218                 : }
         219                 :
         220                 : void
         221               0 : CanvasLayerOGL::RenderLayer(int aPreviousDestination,
         222                 :                             const nsIntPoint& aOffset)
         223                 : {
         224               0 :   UpdateSurface();
         225               0 :   FireDidTransactionCallback();
         226                 :
         227               0 :   mOGLManager->MakeCurrent();
         228                 :
         229                 :   // XXX We're going to need a different program depending on if
         230                 :   // mGLBufferIsPremultiplied is TRUE or not.  The RGBLayerProgram
         231                 :   // assumes that it's true.
         232                 :
         233               0 :   gl()->fActiveTexture(LOCAL_GL_TEXTURE0);
         234                 :
         235               0 :   if (mTexture) {
         236               0 :     gl()->fBindTexture(LOCAL_GL_TEXTURE_2D, mTexture);
         237                 :   }
         238                 :
         239               0 :   ColorTextureLayerProgram *program = nsnull;
         240                 :
         241                 :   bool useGLContext = mCanvasGLContext &&
         242               0 :     mCanvasGLContext->GetContextType() == gl()->GetContextType();
         243                 :
         244               0 :   nsIntRect drawRect = mBounds;
         245                 :
         246               0 :   if (useGLContext) {
         247               0 :     gl()->BindTex2DOffscreen(mCanvasGLContext);
         248               0 :     program = mOGLManager->GetBasicLayerProgram(CanUseOpaqueSurface(), true);
         249               0 :   } else if (mDelayedUpdates) {
         250               0 :     NS_ABORT_IF_FALSE(mCanvasSurface || mDrawTarget, "WebGL canvases should always be using full texture upload");
         251                 :
         252               0 :     drawRect.IntersectRect(drawRect, GetEffectiveVisibleRegion().GetBounds());
         253                 :
         254               0 :     nsRefPtr<gfxASurface> surf = mCanvasSurface;
         255               0 :     if (mDrawTarget) {
         256               0 :       surf = gfxPlatform::GetPlatform()->GetThebesSurfaceForDrawTarget(mDrawTarget);
         257                 :     }
         258                 :
         259                 :     mLayerProgram =
         260                 :       gl()->UploadSurfaceToTexture(surf,
         261                 :                                    nsIntRect(0, 0, drawRect.width, drawRect.height),
         262                 :                                    mTexture,
         263                 :                                    true,
         264               0 :                                    drawRect.TopLeft());
         265                 :   }
         266                 :
         267               0 :   if (!program) {
         268               0 :     program = mOGLManager->GetColorTextureLayerProgram(mLayerProgram);
         269                 :   }
         270                 :
         271                 : #if defined(MOZ_WIDGET_GTK2) && !defined(MOZ_PLATFORM_MAEMO)
         272               0 :   if (mPixmap && !mDelayedUpdates) {
         273               0 :     sGLXLibrary.BindTexImage(mPixmap);
         274                 :   }
         275                 : #endif
         276                 :
         277               0 :   gl()->ApplyFilterToBoundTexture(mFilter);
         278                 :
         279               0 :   program->Activate();
         280               0 :   program->SetLayerQuadRect(drawRect);
         281               0 :   program->SetLayerTransform(GetEffectiveTransform());
         282               0 :   program->SetLayerOpacity(GetEffectiveOpacity());
         283               0 :   program->SetRenderOffset(aOffset);
         284               0 :   program->SetTextureUnit(0);
         285                 :
         286               0 :   mOGLManager->BindAndDrawQuad(program, mNeedsYFlip ? true : false);
         287                 :
         288                 : #if defined(MOZ_WIDGET_GTK2) && !defined(MOZ_PLATFORM_MAEMO)
         289               0 :   if (mPixmap && !mDelayedUpdates) {
         290               0 :     sGLXLibrary.ReleaseTexImage(mPixmap);
         291                 :   }
         292                 : #endif
         293                 :
         294               0 :   if (useGLContext) {
         295               0 :     gl()->UnbindTex2DOffscreen(mCanvasGLContext);
         296                 :   }
         297               0 : }
         298                 :
         299                 : void
         300               0 : CanvasLayerOGL::CleanupResources()
         301                 : {
         302               0 :   if (mTexture) {
         303               0 :     GLContext* cx = mOGLManager->glForResources();
         304               0 :     cx->MakeCurrent();
         305               0 :     cx->fDeleteTextures(1, &mTexture);
         306                 :   }
         307               0 : }
         308                 :
         309                 :
         310               0 : ShadowCanvasLayerOGL::ShadowCanvasLayerOGL(LayerManagerOGL* aManager)
         311                 :   : ShadowCanvasLayer(aManager, nsnull)
         312                 :   , LayerOGL(aManager)
         313               0 :   , mNeedsYFlip(false)
         314                 : {
         315               0 :   mImplData = static_cast<LayerOGL*>(this);
         316               0 : }
         317                 :
         318               0 : ShadowCanvasLayerOGL::~ShadowCanvasLayerOGL()
         319               0 : {}
         320                 :
         321                 : void
         322               0 : ShadowCanvasLayerOGL::Initialize(const Data& aData)
         323                 : {
         324               0 :   NS_RUNTIMEABORT("Incompatibe surface type");
         325               0 : }
         326                 :
         327                 : void
         328               0 : ShadowCanvasLayerOGL::Init(const CanvasSurface& aNewFront, bool needYFlip)
         329                 : {
         330               0 :   nsRefPtr<gfxASurface> surf = ShadowLayerForwarder::OpenDescriptor(aNewFront);
         331                 :
         332               0 :   mTexImage = gl()->CreateTextureImage(surf->GetSize(),
         333                 :                                        surf->GetContentType(),
         334               0 :                                        LOCAL_GL_CLAMP_TO_EDGE);
         335               0 :   mNeedsYFlip = needYFlip;
         336               0 : }
         337                 :
         338                 : void
         339               0 : ShadowCanvasLayerOGL::Swap(const CanvasSurface& aNewFront,
         340                 :                            bool needYFlip,
         341                 :                            CanvasSurface* aNewBack)
         342                 : {
         343               0 :   if (!mDestroyed) {
         344               0 :     nsRefPtr<gfxASurface> surf = ShadowLayerForwarder::OpenDescriptor(aNewFront);
         345               0 :     gfxIntSize sz = surf->GetSize();
         346               0 :     if (!mTexImage || mTexImage->GetSize() != sz ||
         347               0 :         mTexImage->GetContentType() != surf->GetContentType()) {
         348               0 :       Init(aNewFront, needYFlip);
         349                 :     }
         350               0 :     nsIntRegion updateRegion(nsIntRect(0, 0, sz.width, sz.height));
         351               0 :     mTexImage->DirectUpdate(surf, updateRegion);
         352                 :   }
         353                 :
         354               0 :   *aNewBack = aNewFront;
         355               0 : }
         356                 :
         357                 : void
         358               0 : ShadowCanvasLayerOGL::DestroyFrontBuffer()
         359                 : {
         360               0 :   mTexImage = nsnull;
         361               0 : }
         362                 :
         363                 : void
         364               0 : ShadowCanvasLayerOGL::Disconnect()
         365                 : {
         366               0 :   Destroy();
         367               0 : }
         368                 :
         369                 : void
         370               0 : ShadowCanvasLayerOGL::Destroy()
         371                 : {
         372               0 :   if (!mDestroyed) {
         373               0 :     mDestroyed = true;
         374               0 :     mTexImage = nsnull;
         375                 :   }
         376               0 : }
         377                 :
         378                 : Layer*
         379               0 : ShadowCanvasLayerOGL::GetLayer()
         380                 : {
         381               0 :   return this;
         382                 : }
         383                 :
         384                 : void
         385               0 : ShadowCanvasLayerOGL::RenderLayer(int aPreviousFrameBuffer,
         386                 :                                   const nsIntPoint& aOffset)
         387                 : {
         388               0 :   mOGLManager->MakeCurrent();
         389                 :
         390                 :   ColorTextureLayerProgram *program =
         391               0 :     mOGLManager->GetColorTextureLayerProgram(mTexImage->GetShaderProgramType());
         392                 :
         393                 :
         394               0 :   gfx3DMatrix effectiveTransform = GetEffectiveTransform();
         395                 : #ifdef ANDROID
         396                 :   // Bug 691354
         397                 :   // Using the LINEAR filter we get unexplained artifacts.
         398                 :   // Use NEAREST when no scaling is required.
         399                 :   gfxMatrix matrix;
         400                 :   bool is2D = GetEffectiveTransform().Is2D(&matrix);
         401                 :   if (is2D && !matrix.HasNonTranslationOrFlip()) {
         402                 :     mTexImage->SetFilter(gfxPattern::FILTER_NEAREST);
         403                 :   } else {
         404                 :     mTexImage->SetFilter(mFilter);
         405                 :   }
         406                 : #else
         407               0 :   mTexImage->SetFilter(mFilter);
         408                 : #endif
         409                 :
         410                 :
         411               0 :   program->Activate();
         412               0 :   program->SetLayerTransform(effectiveTransform);
         413               0 :   program->SetLayerOpacity(GetEffectiveOpacity());
         414               0 :   program->SetRenderOffset(aOffset);
         415               0 :   program->SetTextureUnit(0);
         416                 :
         417               0 :   mTexImage->BeginTileIteration();
         418               0 :   do {
         419               0 :     TextureImage::ScopedBindTextureAndApplyFilter texBind(mTexImage, LOCAL_GL_TEXTURE0);
         420               0 :     program->SetLayerQuadRect(mTexImage->GetTileRect());
         421               0 :     mOGLManager->BindAndDrawQuad(program, mNeedsYFlip); // FIXME flip order of tiles?
         422               0 :   } while (mTexImage->NextTile());
         423               0 : }
         424                 :
         425                 : void
         426               0 : ShadowCanvasLayerOGL::CleanupResources()
         427                 : {
         428               0 :   DestroyFrontBuffer();
         429               0 : }

Generated by: LCOV version 1.7