LCOV - code coverage report
Current view: directory - gfx/layers/opengl - ImageLayerOGL.cpp (source / functions) Found Hit Coverage
Test: app.info Lines: 344 0 0.0 %
Date: 2012-06-02 Functions: 28 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                 :  *   Vladimir Vukicevic <vladimir@pobox.com>
      24                 :  *
      25                 :  * Alternatively, the contents of this file may be used under the terms of
      26                 :  * either the GNU General Public License Version 2 or later (the "GPL"), or
      27                 :  * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
      28                 :  * in which case the provisions of the GPL or the LGPL are applicable instead
      29                 :  * of those above. If you wish to allow use of your version of this file only
      30                 :  * under the terms of either the GPL or the LGPL, and not to allow others to
      31                 :  * use your version of this file under the terms of the MPL, indicate your
      32                 :  * decision by deleting the provisions above and replace them with the notice
      33                 :  * and other provisions required by the GPL or the LGPL. If you do not delete
      34                 :  * the provisions above, a recipient may use your version of this file under
      35                 :  * the terms of any one of the MPL, the GPL or the LGPL.
      36                 :  *
      37                 :  * ***** END LICENSE BLOCK ***** */
      38                 : 
      39                 : #include "gfxSharedImageSurface.h"
      40                 : 
      41                 : #include "ImageLayerOGL.h"
      42                 : #include "gfxImageSurface.h"
      43                 : #include "yuv_convert.h"
      44                 : #include "GLContextProvider.h"
      45                 : #if defined(MOZ_WIDGET_GTK2) && !defined(MOZ_PLATFORM_MAEMO)
      46                 : # include "GLXLibrary.h"
      47                 : # include "mozilla/X11Util.h"
      48                 : #endif
      49                 : 
      50                 : using namespace mozilla::gl;
      51                 : 
      52                 : namespace mozilla {
      53                 : namespace layers {
      54                 : 
      55                 : /**
      56                 :  * This is an event used to unref a GLContext on the main thread and
      57                 :  * optionally delete a texture associated with that context.
      58                 :  */
      59               0 : class TextureDeleter : public nsRunnable {
      60                 : public:
      61               0 :   TextureDeleter(already_AddRefed<GLContext> aContext,
      62                 :                  GLuint aTexture)
      63               0 :       : mContext(aContext), mTexture(aTexture)
      64                 :   {
      65               0 :     NS_ASSERTION(aTexture, "TextureDeleter instantiated with nothing to do");
      66               0 :   }
      67                 : 
      68               0 :   NS_IMETHOD Run() {
      69               0 :     mContext->MakeCurrent();
      70               0 :     mContext->fDeleteTextures(1, &mTexture);
      71                 : 
      72                 :     // Ensure context is released on the main thread
      73               0 :     mContext = nsnull;
      74               0 :     return NS_OK;
      75                 :   }
      76                 : 
      77                 :   nsRefPtr<GLContext> mContext;
      78                 :   GLuint mTexture;
      79                 : };
      80                 : 
      81                 : void
      82               0 : GLTexture::Allocate(GLContext *aContext)
      83                 : {
      84               0 :   NS_ASSERTION(aContext->IsGlobalSharedContext() ||
      85                 :                NS_IsMainThread(), "Can only allocate texture on main thread or with cx sharing");
      86                 : 
      87               0 :   Release();
      88                 : 
      89               0 :   mContext = aContext;
      90                 : 
      91               0 :   mContext->MakeCurrent();
      92               0 :   mContext->fGenTextures(1, &mTexture);
      93               0 : }
      94                 : 
      95                 : void
      96               0 : GLTexture::TakeFrom(GLTexture *aOther)
      97                 : {
      98               0 :   Release();
      99                 : 
     100               0 :   mContext = aOther->mContext.forget();
     101               0 :   mTexture = aOther->mTexture;
     102               0 :   aOther->mTexture = 0;
     103               0 : }
     104                 : 
     105                 : void
     106               0 : GLTexture::Release()
     107                 : {
     108               0 :   if (!mContext) {
     109               0 :     NS_ASSERTION(!mTexture, "Can't delete texture without a context");
     110               0 :     return;
     111                 :   }
     112                 : 
     113               0 :   if (mContext->IsDestroyed() && !mContext->IsGlobalSharedContext()) {
     114               0 :     mContext = mContext->GetSharedContext();
     115               0 :     if (!mContext) {
     116               0 :       NS_ASSERTION(!mTexture, 
     117                 :                    "Context has been destroyed and couldn't find a shared context!");
     118               0 :       return;
     119                 :     }
     120                 :   }
     121                 : 
     122               0 :   if (mTexture) {
     123               0 :     if (NS_IsMainThread() || mContext->IsGlobalSharedContext()) {
     124               0 :       mContext->MakeCurrent();
     125               0 :       mContext->fDeleteTextures(1, &mTexture);
     126                 :     } else {
     127                 :       nsCOMPtr<nsIRunnable> runnable =
     128               0 :         new TextureDeleter(mContext.forget(), mTexture);
     129               0 :       NS_DispatchToMainThread(runnable);
     130                 :     }
     131                 : 
     132               0 :     mTexture = 0;
     133                 :   }
     134                 : 
     135               0 :   mContext = nsnull;
     136                 : }
     137                 : 
     138               0 : TextureRecycleBin::TextureRecycleBin()
     139               0 :   : mLock("mozilla.layers.TextureRecycleBin.mLock")
     140                 : {
     141               0 : }
     142                 : 
     143                 : void
     144               0 : TextureRecycleBin::RecycleTexture(GLTexture *aTexture, TextureType aType,
     145                 :                            const gfxIntSize& aSize)
     146                 : {
     147               0 :   MutexAutoLock lock(mLock);
     148                 : 
     149               0 :   if (!aTexture->IsAllocated())
     150                 :     return;
     151                 : 
     152               0 :   if (!mRecycledTextures[aType].IsEmpty() && aSize != mRecycledTextureSizes[aType]) {
     153               0 :     mRecycledTextures[aType].Clear();
     154                 :   }
     155               0 :   mRecycledTextureSizes[aType] = aSize;
     156               0 :   mRecycledTextures[aType].AppendElement()->TakeFrom(aTexture);
     157                 : }
     158                 : 
     159                 : void
     160               0 : TextureRecycleBin::GetTexture(TextureType aType, const gfxIntSize& aSize,
     161                 :                        GLContext *aContext, GLTexture *aOutTexture)
     162                 : {
     163               0 :   MutexAutoLock lock(mLock);
     164                 : 
     165               0 :   if (mRecycledTextures[aType].IsEmpty() || mRecycledTextureSizes[aType] != aSize) {
     166               0 :     aOutTexture->Allocate(aContext);
     167                 :     return;
     168                 :   }
     169               0 :   PRUint32 last = mRecycledTextures[aType].Length() - 1;
     170               0 :   aOutTexture->TakeFrom(&mRecycledTextures[aType].ElementAt(last));
     171               0 :   mRecycledTextures[aType].RemoveElementAt(last);
     172                 : }
     173                 : 
     174                 : struct THEBES_API MacIOSurfaceImageOGLBackendData : public ImageBackendData
     175                 : {
     176                 :   GLTexture mTexture;
     177                 : };
     178                 : 
     179                 : #ifdef XP_MACOSX
     180                 : void
     181                 : AllocateTextureIOSurface(MacIOSurfaceImage *aIOImage, mozilla::gl::GLContext* aGL)
     182                 : {
     183                 :   nsAutoPtr<MacIOSurfaceImageOGLBackendData> backendData(
     184                 :     new MacIOSurfaceImageOGLBackendData);
     185                 : 
     186                 :   backendData->mTexture.Allocate(aGL);
     187                 :   aGL->fBindTexture(LOCAL_GL_TEXTURE_RECTANGLE_ARB, backendData->mTexture.GetTextureID());
     188                 :   aGL->fTexParameteri(LOCAL_GL_TEXTURE_RECTANGLE_ARB,
     189                 :                      LOCAL_GL_TEXTURE_MIN_FILTER,
     190                 :                      LOCAL_GL_NEAREST);
     191                 :   aGL->fTexParameteri(LOCAL_GL_TEXTURE_RECTANGLE_ARB,
     192                 :                      LOCAL_GL_TEXTURE_MAG_FILTER,
     193                 :                      LOCAL_GL_NEAREST);
     194                 : 
     195                 :   void *nativeCtx = aGL->GetNativeData(GLContext::NativeGLContext);
     196                 : 
     197                 :   aIOImage->GetIOSurface()->CGLTexImageIOSurface2D(nativeCtx,
     198                 :                                      LOCAL_GL_RGBA, LOCAL_GL_BGRA,
     199                 :                                      LOCAL_GL_UNSIGNED_INT_8_8_8_8_REV, 0);
     200                 : 
     201                 :   aGL->fBindTexture(LOCAL_GL_TEXTURE_RECTANGLE_ARB, 0);
     202                 : 
     203                 :   aIOImage->SetBackendData(LayerManager::LAYERS_OPENGL, backendData.forget());
     204                 : }
     205                 : #endif
     206                 : 
     207                 : Layer*
     208               0 : ImageLayerOGL::GetLayer()
     209                 : {
     210               0 :   return this;
     211                 : }
     212                 : 
     213                 : void
     214               0 : ImageLayerOGL::RenderLayer(int,
     215                 :                            const nsIntPoint& aOffset)
     216                 : {
     217               0 :   nsRefPtr<ImageContainer> container = GetContainer();
     218                 : 
     219               0 :   if (!container)
     220                 :     return;
     221                 : 
     222               0 :   mOGLManager->MakeCurrent();
     223                 : 
     224               0 :   AutoLockImage autoLock(container);
     225                 : 
     226               0 :   Image *image = autoLock.GetImage();
     227               0 :   if (!image) {
     228                 :     return;
     229                 :   }
     230                 : 
     231               0 :   NS_ASSERTION(image->GetFormat() != Image::REMOTE_IMAGE_BITMAP,
     232                 :     "Remote images aren't handled yet in OGL layers!");
     233               0 :   NS_ASSERTION(mScaleMode == SCALE_NONE,
     234                 :     "Scale modes other than none not handled yet in OGL layers!");
     235                 : 
     236               0 :   if (image->GetFormat() == Image::PLANAR_YCBCR) {
     237                 :     PlanarYCbCrImage *yuvImage =
     238               0 :       static_cast<PlanarYCbCrImage*>(image);
     239                 : 
     240               0 :     if (!yuvImage->mBufferSize) {
     241                 :       return;
     242                 :     }
     243                 : 
     244               0 :     if (!yuvImage->GetBackendData(LayerManager::LAYERS_OPENGL)) {
     245               0 :       AllocateTexturesYCbCr(yuvImage);
     246                 :     }
     247                 : 
     248                 :     PlanarYCbCrOGLBackendData *data =
     249               0 :       static_cast<PlanarYCbCrOGLBackendData*>(yuvImage->GetBackendData(LayerManager::LAYERS_OPENGL));
     250                 : 
     251               0 :     if (!data || data->mTextures->GetGLContext() != mOGLManager->glForResources()) {
     252                 :       // XXX - Can this ever happen? If so I need to fix this!
     253                 :       return;
     254                 :     }
     255                 : 
     256               0 :     gl()->MakeCurrent();
     257               0 :     gl()->fActiveTexture(LOCAL_GL_TEXTURE0);
     258               0 :     gl()->fBindTexture(LOCAL_GL_TEXTURE_2D, data->mTextures[0].GetTextureID());
     259               0 :     gl()->ApplyFilterToBoundTexture(mFilter);
     260               0 :     gl()->fActiveTexture(LOCAL_GL_TEXTURE1);
     261               0 :     gl()->fBindTexture(LOCAL_GL_TEXTURE_2D, data->mTextures[1].GetTextureID());
     262               0 :     gl()->ApplyFilterToBoundTexture(mFilter);
     263               0 :     gl()->fActiveTexture(LOCAL_GL_TEXTURE2);
     264               0 :     gl()->fBindTexture(LOCAL_GL_TEXTURE_2D, data->mTextures[2].GetTextureID());
     265               0 :     gl()->ApplyFilterToBoundTexture(mFilter);
     266                 :     
     267               0 :     YCbCrTextureLayerProgram *program = mOGLManager->GetYCbCrLayerProgram();
     268                 : 
     269               0 :     program->Activate();
     270                 :     program->SetLayerQuadRect(nsIntRect(0, 0,
     271                 :                                         yuvImage->mSize.width,
     272               0 :                                         yuvImage->mSize.height));
     273               0 :     program->SetLayerTransform(GetEffectiveTransform());
     274               0 :     program->SetLayerOpacity(GetEffectiveOpacity());
     275               0 :     program->SetRenderOffset(aOffset);
     276               0 :     program->SetYCbCrTextureUnits(0, 1, 2);
     277                 : 
     278                 :     mOGLManager->BindAndDrawQuadWithTextureRect(program,
     279                 :                                                 yuvImage->mData.GetPictureRect(),
     280                 :                                                 nsIntSize(yuvImage->mData.mYSize.width,
     281               0 :                                                           yuvImage->mData.mYSize.height));
     282                 : 
     283                 :     // We shouldn't need to do this, but do it anyway just in case
     284                 :     // someone else forgets.
     285               0 :     gl()->fActiveTexture(LOCAL_GL_TEXTURE0);
     286               0 :   } else if (image->GetFormat() == Image::CAIRO_SURFACE) {
     287                 :     CairoImage *cairoImage =
     288               0 :       static_cast<CairoImage*>(image);
     289                 : 
     290               0 :     if (!cairoImage->mSurface) {
     291                 :       return;
     292                 :     }
     293                 : 
     294               0 :     if (!cairoImage->GetBackendData(LayerManager::LAYERS_OPENGL)) {
     295               0 :       AllocateTexturesCairo(cairoImage);
     296                 :     }
     297                 : 
     298                 :     CairoOGLBackendData *data =
     299               0 :       static_cast<CairoOGLBackendData*>(cairoImage->GetBackendData(LayerManager::LAYERS_OPENGL));
     300                 : 
     301               0 :     if (!data || data->mTexture.GetGLContext() != mOGLManager->glForResources()) {
     302                 :       // XXX - Can this ever happen? If so I need to fix this!
     303                 :       return;
     304                 :     }
     305                 : 
     306               0 :     data->SetTiling(mUseTileSourceRect);
     307               0 :     gl()->MakeCurrent();
     308               0 :     unsigned int iwidth  = cairoImage->mSize.width;
     309               0 :     unsigned int iheight = cairoImage->mSize.height;
     310                 : 
     311               0 :     gl()->fActiveTexture(LOCAL_GL_TEXTURE0);
     312               0 :     gl()->fBindTexture(LOCAL_GL_TEXTURE_2D, data->mTexture.GetTextureID());
     313                 : 
     314                 : #if defined(MOZ_WIDGET_GTK2) && !defined(MOZ_PLATFORM_MAEMO)
     315                 :     GLXPixmap pixmap;
     316                 : 
     317               0 :     if (cairoImage->mSurface) {
     318               0 :         pixmap = sGLXLibrary.CreatePixmap(cairoImage->mSurface);
     319               0 :         NS_ASSERTION(pixmap, "Failed to create pixmap!");
     320               0 :         if (pixmap) {
     321               0 :             sGLXLibrary.BindTexImage(pixmap);
     322                 :         }
     323                 :     }
     324                 : #endif
     325                 : 
     326                 :     ColorTextureLayerProgram *program = 
     327               0 :       mOGLManager->GetColorTextureLayerProgram(data->mLayerProgram);
     328                 : 
     329               0 :     gl()->ApplyFilterToBoundTexture(mFilter);
     330                 : 
     331               0 :     program->Activate();
     332                 :     // The following uniform controls the scaling of the vertex coords.
     333                 :     // Instead of setting the scale here and using coords in the range [0,1], we
     334                 :     // set an identity transform and use pixel coordinates below
     335               0 :     program->SetLayerQuadRect(nsIntRect(0, 0, 1, 1));
     336               0 :     program->SetLayerTransform(GetEffectiveTransform());
     337               0 :     program->SetLayerOpacity(GetEffectiveOpacity());
     338               0 :     program->SetRenderOffset(aOffset);
     339               0 :     program->SetTextureUnit(0);
     340                 : 
     341               0 :     nsIntRect rect = GetVisibleRegion().GetBounds();
     342                 : 
     343               0 :     bool tileIsWholeImage = (mTileSourceRect == nsIntRect(0, 0, iwidth, iheight)) 
     344               0 :                             || !mUseTileSourceRect;
     345                 :     bool imageIsPowerOfTwo = ((iwidth  & (iwidth - 1)) == 0 &&
     346               0 :                               (iheight & (iheight - 1)) == 0);
     347                 :     bool canDoNPOT = (
     348               0 :           gl()->IsExtensionSupported(GLContext::ARB_texture_non_power_of_two) ||
     349               0 :           gl()->IsExtensionSupported(GLContext::OES_texture_npot));
     350                 : 
     351               0 :     GLContext::RectTriangles triangleBuffer;
     352                 :     // do GL_REPEAT if we can - should be the fastest option.
     353                 :     // draw a single rect for the whole region, a little overdraw
     354                 :     // on the gpu should be faster than tesselating
     355                 :     // maybe we can write a shader that can also handle texture subrects
     356                 :     // and repeat?
     357               0 :     if (tileIsWholeImage && (imageIsPowerOfTwo || canDoNPOT)) {
     358                 :         // we need to anchor the repeating texture appropriately
     359                 :         // otherwise it will start from the region border instead
     360                 :         // of the layer origin. This is the offset into the texture
     361                 :         // that the region border represents
     362               0 :         float tex_offset_u = (float)(rect.x % iwidth) / iwidth;
     363               0 :         float tex_offset_v = (float)(rect.y % iheight) / iheight;
     364                 :         triangleBuffer.addRect(rect.x, rect.y,
     365                 :                                rect.x + rect.width, rect.y + rect.height,
     366                 :                                tex_offset_u, tex_offset_v,
     367                 :                                tex_offset_u + (float)rect.width / (float)iwidth,
     368               0 :                                tex_offset_v + (float)rect.height / (float)iheight);
     369                 :     }
     370                 :     // can't do fast path via GL_REPEAT - we have to tessellate individual rects.
     371                 :     else {
     372               0 :         unsigned int twidth = mTileSourceRect.width;
     373               0 :         unsigned int theight = mTileSourceRect.height;
     374                 : 
     375               0 :         nsIntRegion region = GetVisibleRegion();
     376                 :         // image subrect in texture coordinates
     377               0 :         float subrect_tl_u = float(mTileSourceRect.x) / float(iwidth);
     378               0 :         float subrect_tl_v = float(mTileSourceRect.y) / float(iheight);
     379               0 :         float subrect_br_u = float(mTileSourceRect.width + mTileSourceRect.x) / float(iwidth);
     380               0 :         float subrect_br_v = float(mTileSourceRect.height + mTileSourceRect.y) / float(iheight);
     381                 : 
     382                 :         // round rect position down to multiples of texture size
     383                 :         // this way we start at multiples of rect positions
     384               0 :         rect.x = (rect.x / iwidth) * iwidth;
     385               0 :         rect.y = (rect.y / iheight) * iheight;
     386                 :         // round up size to accomodate for rounding down above
     387               0 :         rect.width  = (rect.width / iwidth + 2) * iwidth;
     388               0 :         rect.height = (rect.height / iheight + 2) * iheight;
     389                 : 
     390                 :         // tesselate the visible region with tiles of subrect size
     391               0 :         for (int y = rect.y; y < rect.y + rect.height;  y += theight) {
     392               0 :             for (int x = rect.x; x < rect.x + rect.width; x += twidth) {
     393                 :                 // when we already tessellate, we might as well save on overdraw here
     394               0 :                 if (!region.Intersects(nsIntRect(x, y, twidth, theight))) {
     395               0 :                     continue;
     396                 :                 }
     397                 :                 triangleBuffer.addRect(x, y,
     398                 :                                        x + twidth, y + theight,
     399                 :                                        subrect_tl_u, subrect_tl_v,
     400               0 :                                        subrect_br_u, subrect_br_v);
     401                 :             }
     402                 :         }
     403                 :     }
     404                 :     GLuint vertAttribIndex =
     405               0 :         program->AttribLocation(LayerProgram::VertexAttrib);
     406                 :     GLuint texCoordAttribIndex =
     407               0 :         program->AttribLocation(LayerProgram::TexCoordAttrib);
     408               0 :     NS_ASSERTION(texCoordAttribIndex != GLuint(-1), "no texture coords?");
     409                 : 
     410               0 :     gl()->fBindBuffer(LOCAL_GL_ARRAY_BUFFER, 0);
     411                 :     gl()->fVertexAttribPointer(vertAttribIndex, 2,
     412                 :                                LOCAL_GL_FLOAT, LOCAL_GL_FALSE, 0,
     413               0 :                                triangleBuffer.vertexPointer());
     414                 : 
     415                 :     gl()->fVertexAttribPointer(texCoordAttribIndex, 2,
     416                 :                                LOCAL_GL_FLOAT, LOCAL_GL_FALSE, 0,
     417               0 :                                triangleBuffer.texCoordPointer());
     418                 :     {
     419               0 :         gl()->fEnableVertexAttribArray(texCoordAttribIndex);
     420                 :         {
     421               0 :             gl()->fEnableVertexAttribArray(vertAttribIndex);
     422               0 :             gl()->fDrawArrays(LOCAL_GL_TRIANGLES, 0, triangleBuffer.elements());
     423               0 :             gl()->fDisableVertexAttribArray(vertAttribIndex);
     424                 :         }
     425               0 :         gl()->fDisableVertexAttribArray(texCoordAttribIndex);
     426                 :     }
     427                 : #if defined(MOZ_WIDGET_GTK2) && !defined(MOZ_PLATFORM_MAEMO)
     428               0 :     if (cairoImage->mSurface && pixmap) {
     429               0 :         sGLXLibrary.ReleaseTexImage(pixmap);
     430               0 :         sGLXLibrary.DestroyPixmap(pixmap);
     431                 :     }
     432                 : #endif
     433                 : #ifdef XP_MACOSX
     434                 :   } else if (image->GetFormat() == Image::MAC_IO_SURFACE) {
     435                 :      MacIOSurfaceImage *ioImage =
     436                 :        static_cast<MacIOSurfaceImage*>(image);
     437                 : 
     438                 :      if (!mOGLManager->GetThebesLayerCallback()) {
     439                 :        // If its an empty transaction we still need to update
     440                 :        // the plugin IO Surface and make sure we grab the
     441                 :        // new image
     442                 :        ioImage->Update(GetContainer());
     443                 :        image = nsnull;
     444                 :        autoLock.Refresh();
     445                 :        image = autoLock.GetImage();
     446                 :        gl()->MakeCurrent();
     447                 :        ioImage = static_cast<MacIOSurfaceImage*>(image);
     448                 :      }
     449                 : 
     450                 :      if (!ioImage) {
     451                 :        return;
     452                 :      }
     453                 : 
     454                 :      gl()->fActiveTexture(LOCAL_GL_TEXTURE0);
     455                 : 
     456                 :      if (!ioImage->GetBackendData(LayerManager::LAYERS_OPENGL)) {
     457                 :        AllocateTextureIOSurface(ioImage, gl());
     458                 :      }
     459                 : 
     460                 :      MacIOSurfaceImageOGLBackendData *data =
     461                 :       static_cast<MacIOSurfaceImageOGLBackendData*>(ioImage->GetBackendData(LayerManager::LAYERS_OPENGL));
     462                 : 
     463                 :      gl()->fActiveTexture(LOCAL_GL_TEXTURE0);
     464                 :      gl()->fBindTexture(LOCAL_GL_TEXTURE_RECTANGLE_ARB, data->mTexture.GetTextureID());
     465                 : 
     466                 :      ColorTextureLayerProgram *program = 
     467                 :        mOGLManager->GetRGBARectLayerProgram();
     468                 :      
     469                 :      program->Activate();
     470                 :      if (program->GetTexCoordMultiplierUniformLocation() != -1) {
     471                 :        // 2DRect case, get the multiplier right for a sampler2DRect
     472                 :        float f[] = { float(ioImage->GetSize().width), float(ioImage->GetSize().height) };
     473                 :        program->SetUniform(program->GetTexCoordMultiplierUniformLocation(),
     474                 :                            2, f);
     475                 :      } else {
     476                 :        NS_ASSERTION(0, "no rects?");
     477                 :      }
     478                 :      
     479                 :      program->SetLayerQuadRect(nsIntRect(0, 0, 
     480                 :                                          ioImage->GetSize().width, 
     481                 :                                          ioImage->GetSize().height));
     482                 :      program->SetLayerTransform(GetEffectiveTransform());
     483                 :      program->SetLayerOpacity(GetEffectiveOpacity());
     484                 :      program->SetRenderOffset(aOffset);
     485                 :      program->SetTextureUnit(0);
     486                 :     
     487                 :      mOGLManager->BindAndDrawQuad(program);
     488                 :      gl()->fBindTexture(LOCAL_GL_TEXTURE_RECTANGLE_ARB, 0);
     489                 : #endif
     490                 :   }
     491               0 :   GetContainer()->NotifyPaintedImage(image);
     492                 : }
     493                 : 
     494                 : static void
     495               0 : InitTexture(GLContext* aGL, GLuint aTexture, GLenum aFormat, const gfxIntSize& aSize)
     496                 : {
     497               0 :   aGL->fBindTexture(LOCAL_GL_TEXTURE_2D, aTexture);
     498               0 :   aGL->fTexParameteri(LOCAL_GL_TEXTURE_2D, LOCAL_GL_TEXTURE_MIN_FILTER, LOCAL_GL_LINEAR);
     499               0 :   aGL->fTexParameteri(LOCAL_GL_TEXTURE_2D, LOCAL_GL_TEXTURE_MAG_FILTER, LOCAL_GL_LINEAR);
     500               0 :   aGL->fTexParameteri(LOCAL_GL_TEXTURE_2D, LOCAL_GL_TEXTURE_WRAP_S, LOCAL_GL_CLAMP_TO_EDGE);
     501               0 :   aGL->fTexParameteri(LOCAL_GL_TEXTURE_2D, LOCAL_GL_TEXTURE_WRAP_T, LOCAL_GL_CLAMP_TO_EDGE);
     502                 : 
     503                 :   aGL->fTexImage2D(LOCAL_GL_TEXTURE_2D,
     504                 :                    0,
     505                 :                    aFormat,
     506                 :                    aSize.width,
     507                 :                    aSize.height,
     508                 :                    0,
     509                 :                    aFormat,
     510                 :                    LOCAL_GL_UNSIGNED_BYTE,
     511               0 :                    NULL);
     512               0 : }
     513                 : 
     514                 : static void
     515               0 : UploadYUVToTexture(GLContext* gl, const PlanarYCbCrImage::Data& aData, 
     516                 :                    GLTexture* aYTexture,
     517                 :                    GLTexture* aUTexture,
     518                 :                    GLTexture* aVTexture)
     519                 : {
     520               0 :   nsIntRect size(0, 0, aData.mYSize.width, aData.mYSize.height);
     521               0 :   GLuint texture = aYTexture->GetTextureID();
     522                 :   nsRefPtr<gfxASurface> surf = new gfxImageSurface(aData.mYChannel,
     523                 :                                                    aData.mYSize,
     524                 :                                                    aData.mYStride,
     525               0 :                                                    gfxASurface::ImageFormatA8);
     526               0 :   gl->UploadSurfaceToTexture(surf, size, texture, true);
     527                 :   
     528               0 :   size = nsIntRect(0, 0, aData.mCbCrSize.width, aData.mCbCrSize.height);
     529               0 :   texture = aUTexture->GetTextureID();
     530                 :   surf = new gfxImageSurface(aData.mCbChannel,
     531                 :                              aData.mCbCrSize,
     532                 :                              aData.mCbCrStride,
     533               0 :                              gfxASurface::ImageFormatA8);
     534               0 :   gl->UploadSurfaceToTexture(surf, size, texture, true);
     535                 : 
     536               0 :   texture = aVTexture->GetTextureID();
     537                 :   surf = new gfxImageSurface(aData.mCrChannel,
     538                 :                              aData.mCbCrSize,
     539                 :                              aData.mCbCrStride,
     540               0 :                              gfxASurface::ImageFormatA8);
     541               0 :   gl->UploadSurfaceToTexture(surf, size, texture, true);
     542               0 : }
     543                 : 
     544               0 : ImageLayerOGL::ImageLayerOGL(LayerManagerOGL *aManager)
     545                 :   : ImageLayer(aManager, NULL)
     546                 :   , LayerOGL(aManager)
     547               0 :   , mTextureRecycleBin(new TextureRecycleBin())
     548                 : { 
     549               0 :   mImplData = static_cast<LayerOGL*>(this);
     550               0 : }
     551                 : 
     552                 : void
     553               0 : ImageLayerOGL::AllocateTexturesYCbCr(PlanarYCbCrImage *aImage)
     554                 : {
     555               0 :   if (!aImage->mBufferSize)
     556               0 :     return;
     557                 : 
     558                 :   nsAutoPtr<PlanarYCbCrOGLBackendData> backendData(
     559               0 :     new PlanarYCbCrOGLBackendData);
     560                 : 
     561               0 :   PlanarYCbCrImage::Data &data = aImage->mData;
     562                 : 
     563               0 :   GLContext *gl = mOGLManager->glForResources();
     564                 : 
     565               0 :   gl->MakeCurrent();
     566                 :  
     567               0 :   mTextureRecycleBin->GetTexture(TextureRecycleBin::TEXTURE_Y, data.mYSize, gl, &backendData->mTextures[0]);
     568               0 :   InitTexture(gl, backendData->mTextures[0].GetTextureID(), LOCAL_GL_LUMINANCE, data.mYSize);
     569                 : 
     570               0 :   mTextureRecycleBin->GetTexture(TextureRecycleBin::TEXTURE_C, data.mCbCrSize, gl, &backendData->mTextures[1]);
     571               0 :   InitTexture(gl, backendData->mTextures[1].GetTextureID(), LOCAL_GL_LUMINANCE, data.mCbCrSize);
     572                 : 
     573               0 :   mTextureRecycleBin->GetTexture(TextureRecycleBin::TEXTURE_C, data.mCbCrSize, gl, &backendData->mTextures[2]);
     574               0 :   InitTexture(gl, backendData->mTextures[2].GetTextureID(), LOCAL_GL_LUMINANCE, data.mCbCrSize);
     575                 : 
     576                 :   UploadYUVToTexture(gl, aImage->mData,
     577               0 :                      &backendData->mTextures[0],
     578               0 :                      &backendData->mTextures[1],
     579               0 :                      &backendData->mTextures[2]);
     580                 : 
     581               0 :   backendData->mYSize = aImage->mData.mYSize;
     582               0 :   backendData->mCbCrSize = aImage->mData.mCbCrSize;
     583               0 :   backendData->mTextureRecycleBin = mTextureRecycleBin;
     584                 : 
     585               0 :   aImage->SetBackendData(LayerManager::LAYERS_OPENGL, backendData.forget());
     586                 : }
     587                 : 
     588                 : void
     589               0 : ImageLayerOGL::AllocateTexturesCairo(CairoImage *aImage)
     590                 : {
     591                 :   nsAutoPtr<CairoOGLBackendData> backendData(
     592               0 :     new CairoOGLBackendData);
     593                 : 
     594               0 :   GLTexture &texture = backendData->mTexture;
     595                 : 
     596               0 :   texture.Allocate(mOGLManager->glForResources());
     597                 : 
     598               0 :   if (!texture.IsAllocated()) {
     599                 :     return;
     600                 :   }
     601                 : 
     602               0 :   mozilla::gl::GLContext *gl = texture.GetGLContext();
     603               0 :   gl->MakeCurrent();
     604                 : 
     605               0 :   GLuint tex = texture.GetTextureID();
     606               0 :   gl->fActiveTexture(LOCAL_GL_TEXTURE0);
     607                 : 
     608                 : #if defined(MOZ_WIDGET_GTK2) && !defined(MOZ_PLATFORM_MAEMO)
     609               0 :   if (sGLXLibrary.SupportsTextureFromPixmap(aImage->mSurface)) {
     610               0 :     if (aImage->mSurface->GetContentType() == gfxASurface::CONTENT_COLOR_ALPHA) {
     611               0 :       backendData->mLayerProgram = gl::RGBALayerProgramType;
     612                 :     } else {
     613               0 :       backendData->mLayerProgram = gl::RGBXLayerProgramType;
     614                 :     }
     615                 : 
     616               0 :     aImage->SetBackendData(LayerManager::LAYERS_OPENGL, backendData.forget());
     617                 :     return;
     618                 :   }
     619                 : #endif
     620               0 :   backendData->mLayerProgram =
     621                 :     gl->UploadSurfaceToTexture(aImage->mSurface,
     622                 :                                nsIntRect(0,0, aImage->mSize.width, aImage->mSize.height),
     623               0 :                                tex, true);
     624                 : 
     625               0 :   aImage->SetBackendData(LayerManager::LAYERS_OPENGL, backendData.forget());
     626                 : }
     627                 : 
     628               0 : void CairoOGLBackendData::SetTiling(bool aTiling)
     629                 : {
     630               0 :   if (aTiling == mTiling)
     631               0 :       return;
     632               0 :   mozilla::gl::GLContext *gl = mTexture.GetGLContext();
     633               0 :   gl->MakeCurrent();
     634               0 :   gl->fActiveTexture(LOCAL_GL_TEXTURE0);
     635               0 :   gl->fBindTexture(LOCAL_GL_TEXTURE_2D, mTexture.GetTextureID());
     636               0 :   mTiling = aTiling;
     637                 : 
     638               0 :   if (aTiling) {
     639               0 :     gl->fTexParameteri(LOCAL_GL_TEXTURE_2D, LOCAL_GL_TEXTURE_WRAP_S, LOCAL_GL_REPEAT);
     640               0 :     gl->fTexParameteri(LOCAL_GL_TEXTURE_2D, LOCAL_GL_TEXTURE_WRAP_T, LOCAL_GL_REPEAT);
     641                 :   } else {
     642               0 :     gl->fTexParameteri(LOCAL_GL_TEXTURE_2D, LOCAL_GL_TEXTURE_WRAP_S, LOCAL_GL_CLAMP_TO_EDGE);
     643               0 :     gl->fTexParameteri(LOCAL_GL_TEXTURE_2D, LOCAL_GL_TEXTURE_WRAP_T, LOCAL_GL_CLAMP_TO_EDGE);
     644                 :   }
     645                 : }
     646                 : 
     647               0 : ShadowImageLayerOGL::ShadowImageLayerOGL(LayerManagerOGL* aManager)
     648                 :   : ShadowImageLayer(aManager, nsnull)
     649               0 :   , LayerOGL(aManager)
     650                 : {
     651               0 :   mImplData = static_cast<LayerOGL*>(this);
     652               0 : }
     653                 : 
     654               0 : ShadowImageLayerOGL::~ShadowImageLayerOGL()
     655               0 : {}
     656                 : 
     657                 : bool
     658               0 : ShadowImageLayerOGL::Init(const SharedImage& aFront)
     659                 : {
     660               0 :   if (aFront.type() == SharedImage::TSurfaceDescriptor) {
     661               0 :     SurfaceDescriptor desc = aFront.get_SurfaceDescriptor();
     662                 :     nsRefPtr<gfxASurface> surf =
     663               0 :       ShadowLayerForwarder::OpenDescriptor(desc);
     664               0 :     mSize = surf->GetSize();
     665               0 :     mTexImage = gl()->CreateTextureImage(nsIntSize(mSize.width, mSize.height),
     666                 :                                          surf->GetContentType(),
     667               0 :                                          LOCAL_GL_CLAMP_TO_EDGE);
     668               0 :     return true;
     669                 :   } else {
     670               0 :     YUVImage yuv = aFront.get_YUVImage();
     671                 : 
     672                 :     nsRefPtr<gfxSharedImageSurface> surfY =
     673               0 :       gfxSharedImageSurface::Open(yuv.Ydata());
     674                 :     nsRefPtr<gfxSharedImageSurface> surfU =
     675               0 :       gfxSharedImageSurface::Open(yuv.Udata());
     676                 :     nsRefPtr<gfxSharedImageSurface> surfV =
     677               0 :       gfxSharedImageSurface::Open(yuv.Vdata());
     678                 : 
     679               0 :     mSize = surfY->GetSize();
     680               0 :     mCbCrSize = surfU->GetSize();
     681                 : 
     682               0 :     if (!mYUVTexture[0].IsAllocated()) {
     683               0 :       mYUVTexture[0].Allocate(mOGLManager->glForResources());
     684               0 :       mYUVTexture[1].Allocate(mOGLManager->glForResources());
     685               0 :       mYUVTexture[2].Allocate(mOGLManager->glForResources());
     686                 :     }
     687                 : 
     688               0 :     NS_ASSERTION(mYUVTexture[0].IsAllocated() &&
     689                 :                  mYUVTexture[1].IsAllocated() &&
     690                 :                  mYUVTexture[2].IsAllocated(),
     691                 :                  "Texture allocation failed!");
     692                 : 
     693               0 :     gl()->MakeCurrent();
     694               0 :     InitTexture(gl(), mYUVTexture[0].GetTextureID(), LOCAL_GL_LUMINANCE, mSize);
     695               0 :     InitTexture(gl(), mYUVTexture[1].GetTextureID(), LOCAL_GL_LUMINANCE, mCbCrSize);
     696               0 :     InitTexture(gl(), mYUVTexture[2].GetTextureID(), LOCAL_GL_LUMINANCE, mCbCrSize);
     697               0 :     return true;
     698                 :   }
     699                 :   return false;
     700                 : }
     701                 : 
     702                 : void
     703               0 : ShadowImageLayerOGL::Swap(const SharedImage& aNewFront,
     704                 :                           SharedImage* aNewBack)
     705                 : {
     706               0 :   if (!mDestroyed) {
     707               0 :     if (aNewFront.type() == SharedImage::TSurfaceDescriptor) {
     708                 :       nsRefPtr<gfxASurface> surf =
     709               0 :         ShadowLayerForwarder::OpenDescriptor(aNewFront.get_SurfaceDescriptor());
     710               0 :       gfxIntSize size = surf->GetSize();
     711               0 :       if (mSize != size || !mTexImage ||
     712               0 :           mTexImage->GetContentType() != surf->GetContentType()) {
     713               0 :         Init(aNewFront);
     714                 :       }
     715                 :       // XXX this is always just ridiculously slow
     716               0 :       nsIntRegion updateRegion(nsIntRect(0, 0, size.width, size.height));
     717               0 :       mTexImage->DirectUpdate(surf, updateRegion);
     718                 :     } else {
     719               0 :       const YUVImage& yuv = aNewFront.get_YUVImage();
     720                 : 
     721                 :       nsRefPtr<gfxSharedImageSurface> surfY =
     722               0 :         gfxSharedImageSurface::Open(yuv.Ydata());
     723                 :       nsRefPtr<gfxSharedImageSurface> surfU =
     724               0 :         gfxSharedImageSurface::Open(yuv.Udata());
     725                 :       nsRefPtr<gfxSharedImageSurface> surfV =
     726               0 :         gfxSharedImageSurface::Open(yuv.Vdata());
     727               0 :       mPictureRect = yuv.picture();
     728                 : 
     729               0 :       gfxIntSize size = surfY->GetSize();
     730               0 :       gfxIntSize CbCrSize = surfU->GetSize();
     731               0 :       if (size != mSize || mCbCrSize != CbCrSize || !mYUVTexture[0].IsAllocated()) {
     732               0 :         Init(aNewFront);
     733                 :       }
     734                 : 
     735               0 :       PlanarYCbCrImage::Data data;
     736               0 :       data.mYChannel = surfY->Data();
     737               0 :       data.mYStride = surfY->Stride();
     738               0 :       data.mYSize = surfY->GetSize();
     739               0 :       data.mCbChannel = surfU->Data();
     740               0 :       data.mCrChannel = surfV->Data();
     741               0 :       data.mCbCrStride = surfU->Stride();
     742               0 :       data.mCbCrSize = surfU->GetSize();
     743                 : 
     744               0 :       UploadYUVToTexture(gl(), data, &mYUVTexture[0], &mYUVTexture[1], &mYUVTexture[2]);
     745                 :     }
     746                 :   }
     747                 : 
     748               0 :   *aNewBack = aNewFront;
     749               0 : }
     750                 : 
     751                 : void
     752               0 : ShadowImageLayerOGL::Disconnect()
     753                 : {
     754               0 :   Destroy();
     755               0 : }
     756                 : 
     757                 : void
     758               0 : ShadowImageLayerOGL::Destroy()
     759                 : {
     760               0 :   if (!mDestroyed) {
     761               0 :     mDestroyed = true;
     762               0 :     CleanupResources();
     763                 :   }
     764               0 : }
     765                 : 
     766                 : Layer*
     767               0 : ShadowImageLayerOGL::GetLayer()
     768                 : {
     769               0 :   return this;
     770                 : }
     771                 : 
     772                 : void
     773               0 : ShadowImageLayerOGL::RenderLayer(int aPreviousFrameBuffer,
     774                 :                                  const nsIntPoint& aOffset)
     775                 : {
     776               0 :   mOGLManager->MakeCurrent();
     777                 : 
     778               0 :   if (mTexImage) {
     779                 :     ColorTextureLayerProgram *colorProgram =
     780               0 :       mOGLManager->GetColorTextureLayerProgram(mTexImage->GetShaderProgramType());
     781                 : 
     782               0 :     colorProgram->Activate();
     783               0 :     colorProgram->SetTextureUnit(0);
     784               0 :     colorProgram->SetLayerTransform(GetEffectiveTransform());
     785               0 :     colorProgram->SetLayerOpacity(GetEffectiveOpacity());
     786               0 :     colorProgram->SetRenderOffset(aOffset);
     787                 : 
     788               0 :     mTexImage->SetFilter(mFilter);
     789               0 :     mTexImage->BeginTileIteration();
     790               0 :     do {
     791               0 :       TextureImage::ScopedBindTextureAndApplyFilter texBind(mTexImage, LOCAL_GL_TEXTURE0);
     792               0 :       colorProgram->SetLayerQuadRect(mTexImage->GetTileRect());
     793               0 :       mOGLManager->BindAndDrawQuad(colorProgram);
     794               0 :     } while (mTexImage->NextTile());
     795                 :   } else {
     796               0 :     gl()->fActiveTexture(LOCAL_GL_TEXTURE0);
     797               0 :     gl()->fBindTexture(LOCAL_GL_TEXTURE_2D, mYUVTexture[0].GetTextureID());
     798               0 :     gl()->ApplyFilterToBoundTexture(mFilter);
     799               0 :     gl()->fActiveTexture(LOCAL_GL_TEXTURE1);
     800               0 :     gl()->fBindTexture(LOCAL_GL_TEXTURE_2D, mYUVTexture[1].GetTextureID());
     801               0 :     gl()->ApplyFilterToBoundTexture(mFilter);
     802               0 :     gl()->fActiveTexture(LOCAL_GL_TEXTURE2);
     803               0 :     gl()->fBindTexture(LOCAL_GL_TEXTURE_2D, mYUVTexture[2].GetTextureID());
     804               0 :     gl()->ApplyFilterToBoundTexture(mFilter);
     805                 : 
     806               0 :     YCbCrTextureLayerProgram *yuvProgram = mOGLManager->GetYCbCrLayerProgram();
     807                 : 
     808               0 :     yuvProgram->Activate();
     809                 :     yuvProgram->SetLayerQuadRect(nsIntRect(0, 0,
     810                 :                                            mPictureRect.width,
     811               0 :                                            mPictureRect.height));
     812               0 :     yuvProgram->SetYCbCrTextureUnits(0, 1, 2);
     813               0 :     yuvProgram->SetLayerTransform(GetEffectiveTransform());
     814               0 :     yuvProgram->SetLayerOpacity(GetEffectiveOpacity());
     815               0 :     yuvProgram->SetRenderOffset(aOffset);
     816                 : 
     817                 :     mOGLManager->BindAndDrawQuadWithTextureRect(yuvProgram,
     818                 :                                                 mPictureRect,
     819               0 :                                                 nsIntSize(mSize.width, mSize.height));
     820                 :  }
     821               0 : }
     822                 : 
     823                 : void
     824               0 : ShadowImageLayerOGL::CleanupResources()
     825                 : {
     826               0 :   mTexImage = nsnull;
     827               0 : }
     828                 : 
     829                 : } /* layers */
     830                 : } /* mozilla */

Generated by: LCOV version 1.7