gfx/gl/GLScreenBuffer.cpp

Sat, 03 Jan 2015 20:18:00 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Sat, 03 Jan 2015 20:18:00 +0100
branch
TOR_BUG_3246
changeset 7
129ffea94266
permissions
-rwxr-xr-x

Conditionally enable double key logic according to:
private browsing mode or privacy.thirdparty.isolate preference and
implement in GetCookieStringCommon and FindCookie where it counts...
With some reservations of how to convince FindCookie users to test
condition and pass a nullptr when disabling double key logic.

     1 /* -*- Mode: c++; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40; -*- */
     2 /* This Source Code Form is subject to the terms of the Mozilla Public
     3  * License, v. 2.0. If a copy of the MPL was not distributed with this
     4  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
     6 #include "GLScreenBuffer.h"
     8 #include <cstring>
     9 #include "gfxImageSurface.h"
    10 #include "GLContext.h"
    11 #include "GLBlitHelper.h"
    12 #include "GLReadTexImageHelper.h"
    13 #include "SharedSurfaceGL.h"
    14 #include "SurfaceStream.h"
    15 #ifdef MOZ_WIDGET_GONK
    16 #include "SharedSurfaceGralloc.h"
    17 #include "nsXULAppAPI.h"
    18 #endif
    19 #ifdef XP_MACOSX
    20 #include "SharedSurfaceIO.h"
    21 #endif
    22 #include "ScopedGLHelpers.h"
    23 #include "gfx2DGlue.h"
    25 using namespace mozilla::gfx;
    27 namespace mozilla {
    28 namespace gl {
    30 GLScreenBuffer*
    31 GLScreenBuffer::Create(GLContext* gl,
    32                      const gfx::IntSize& size,
    33                      const SurfaceCaps& caps)
    34 {
    35     if (caps.antialias &&
    36         !gl->IsSupported(GLFeature::framebuffer_multisample))
    37     {
    38         return nullptr;
    39     }
    41     SurfaceFactory_GL* factory = nullptr;
    43 #ifdef MOZ_WIDGET_GONK
    44     /* On B2G, we want a Gralloc factory, and we want one right at the start */
    45     if (!factory &&
    46         caps.surfaceAllocator &&
    47         XRE_GetProcessType() != GeckoProcessType_Default)
    48     {
    49         factory = new SurfaceFactory_Gralloc(gl, caps);
    50     }
    51 #endif
    52 #ifdef XP_MACOSX
    53     /* On OSX, we want an IOSurface factory, and we want one right at the start */
    54     if (!factory)
    55     {
    56         factory = new SurfaceFactory_IOSurface(gl, caps);
    57     }
    58 #endif
    60     if (!factory)
    61         factory = new SurfaceFactory_Basic(gl, caps);
    63     SurfaceStream* stream = SurfaceStream::CreateForType(
    64         SurfaceStream::ChooseGLStreamType(SurfaceStream::MainThread,
    65                                           caps.preserve),
    66         gl,
    67         nullptr);
    69     return new GLScreenBuffer(gl, caps, factory, stream);
    70 }
    72 GLScreenBuffer::~GLScreenBuffer()
    73 {
    74     delete mDraw;
    75     delete mRead;
    77     // bug 914823: it is crucial to destroy the Factory _after_ we destroy
    78     // the SharedSurfaces around here! Reason: the shared surfaces will want
    79     // to ask the Allocator (e.g. the ClientLayerManager) to destroy their
    80     // buffers, but that Allocator may be kept alive by the Factory,
    81     // as it currently the case in SurfaceFactory_Gralloc holding a nsRefPtr
    82     // to the Allocator!
    83     delete mFactory;
    84 }
    87 void
    88 GLScreenBuffer::BindAsFramebuffer(GLContext* const gl, GLenum target) const
    89 {
    90     GLuint drawFB = DrawFB();
    91     GLuint readFB = ReadFB();
    93     if (!gl->IsSupported(GLFeature::framebuffer_blit)) {
    94         MOZ_ASSERT(drawFB == readFB);
    95         gl->raw_fBindFramebuffer(target, readFB);
    96         return;
    97     }
    99     switch (target) {
   100     case LOCAL_GL_FRAMEBUFFER:
   101         gl->raw_fBindFramebuffer(LOCAL_GL_DRAW_FRAMEBUFFER_EXT, drawFB);
   102         gl->raw_fBindFramebuffer(LOCAL_GL_READ_FRAMEBUFFER_EXT, readFB);
   103         break;
   105     case LOCAL_GL_DRAW_FRAMEBUFFER_EXT:
   106         if (!gl->IsSupported(GLFeature::framebuffer_blit))
   107             NS_WARNING("DRAW_FRAMEBUFFER requested but unavailable.");
   109         gl->raw_fBindFramebuffer(LOCAL_GL_DRAW_FRAMEBUFFER_EXT, drawFB);
   110         break;
   112     case LOCAL_GL_READ_FRAMEBUFFER_EXT:
   113         if (!gl->IsSupported(GLFeature::framebuffer_blit))
   114             NS_WARNING("READ_FRAMEBUFFER requested but unavailable.");
   116         gl->raw_fBindFramebuffer(LOCAL_GL_READ_FRAMEBUFFER_EXT, readFB);
   117         break;
   119     default:
   120         MOZ_CRASH("Bad `target` for BindFramebuffer.");
   121     }
   122 }
   124 void
   125 GLScreenBuffer::BindFB(GLuint fb)
   126 {
   127     GLuint drawFB = DrawFB();
   128     GLuint readFB = ReadFB();
   130     mUserDrawFB = fb;
   131     mUserReadFB = fb;
   132     mInternalDrawFB = (fb == 0) ? drawFB : fb;
   133     mInternalReadFB = (fb == 0) ? readFB : fb;
   135     if (mInternalDrawFB == mInternalReadFB) {
   136         mGL->raw_fBindFramebuffer(LOCAL_GL_FRAMEBUFFER, mInternalDrawFB);
   137     } else {
   138         MOZ_ASSERT(mGL->IsSupported(GLFeature::framebuffer_blit));
   139         mGL->raw_fBindFramebuffer(LOCAL_GL_DRAW_FRAMEBUFFER_EXT, mInternalDrawFB);
   140         mGL->raw_fBindFramebuffer(LOCAL_GL_READ_FRAMEBUFFER_EXT, mInternalReadFB);
   141     }
   143 #ifdef DEBUG
   144     mInInternalMode_DrawFB = false;
   145     mInInternalMode_ReadFB = false;
   146 #endif
   147 }
   149 void
   150 GLScreenBuffer::BindDrawFB(GLuint fb)
   151 {
   152     if (!mGL->IsSupported(GLFeature::framebuffer_blit)) {
   153         NS_WARNING("DRAW_FRAMEBUFFER requested, but unsupported.");
   155         mGL->raw_fBindFramebuffer(LOCAL_GL_DRAW_FRAMEBUFFER_EXT, fb);
   156     } else {
   157         GLuint drawFB = DrawFB();
   158         mUserDrawFB = fb;
   159         mInternalDrawFB = (fb == 0) ? drawFB : fb;
   161         mGL->raw_fBindFramebuffer(LOCAL_GL_DRAW_FRAMEBUFFER_EXT, mInternalDrawFB);
   162     }
   164 #ifdef DEBUG
   165     mInInternalMode_DrawFB = false;
   166 #endif
   167 }
   169 void
   170 GLScreenBuffer::BindReadFB(GLuint fb)
   171 {
   172     if (!mGL->IsSupported(GLFeature::framebuffer_blit)) {
   173         NS_WARNING("READ_FRAMEBUFFER requested, but unsupported.");
   175         mGL->raw_fBindFramebuffer(LOCAL_GL_READ_FRAMEBUFFER_EXT, fb);
   176     } else {
   177         GLuint readFB = ReadFB();
   178         mUserReadFB = fb;
   179         mInternalReadFB = (fb == 0) ? readFB : fb;
   181         mGL->raw_fBindFramebuffer(LOCAL_GL_READ_FRAMEBUFFER_EXT, mInternalReadFB);
   182     }
   184 #ifdef DEBUG
   185     mInInternalMode_ReadFB = false;
   186 #endif
   187 }
   189 void
   190 GLScreenBuffer::BindDrawFB_Internal(GLuint fb)
   191 {
   192   mInternalDrawFB = mUserDrawFB = fb;
   193   mGL->raw_fBindFramebuffer(LOCAL_GL_DRAW_FRAMEBUFFER_EXT, mInternalDrawFB);
   195 #ifdef DEBUG
   196     mInInternalMode_DrawFB = true;
   197 #endif
   198 }
   200 void
   201 GLScreenBuffer::BindReadFB_Internal(GLuint fb)
   202 {
   203   mInternalReadFB = mUserReadFB = fb;
   204   mGL->raw_fBindFramebuffer(LOCAL_GL_READ_FRAMEBUFFER_EXT, mInternalReadFB);
   206 #ifdef DEBUG
   207     mInInternalMode_ReadFB = true;
   208 #endif
   209 }
   212 GLuint
   213 GLScreenBuffer::GetDrawFB() const
   214 {
   215 #ifdef DEBUG
   216     MOZ_ASSERT(mGL->IsCurrent());
   217     MOZ_ASSERT(!mInInternalMode_DrawFB);
   219     // Don't need a branch here, because:
   220     // LOCAL_GL_DRAW_FRAMEBUFFER_BINDING_EXT == LOCAL_GL_FRAMEBUFFER_BINDING == 0x8CA6
   221     // We use raw_ here because this is debug code and we need to see what
   222     // the driver thinks.
   223     GLuint actual = 0;
   224     mGL->raw_fGetIntegerv(LOCAL_GL_DRAW_FRAMEBUFFER_BINDING_EXT, (GLint*)&actual);
   226     GLuint predicted = mInternalDrawFB;
   227     if (predicted != actual) {
   228         printf_stderr("Misprediction: Bound draw FB predicted: %d. Was: %d.\n",
   229                       predicted, actual);
   230         MOZ_ASSERT(false, "Draw FB binding misprediction!");
   231     }
   232 #endif
   234     return mUserDrawFB;
   235 }
   237 GLuint
   238 GLScreenBuffer::GetReadFB() const
   239 {
   240 #ifdef DEBUG
   241     MOZ_ASSERT(mGL->IsCurrent());
   242     MOZ_ASSERT(!mInInternalMode_ReadFB);
   244     // We use raw_ here because this is debug code and we need to see what
   245     // the driver thinks.
   246     GLuint actual = 0;
   247     if (mGL->IsSupported(GLFeature::framebuffer_blit))
   248         mGL->raw_fGetIntegerv(LOCAL_GL_READ_FRAMEBUFFER_BINDING_EXT, (GLint*)&actual);
   249     else
   250         mGL->raw_fGetIntegerv(LOCAL_GL_FRAMEBUFFER_BINDING, (GLint*)&actual);
   252     GLuint predicted = mInternalReadFB;
   253     if (predicted != actual) {
   254         printf_stderr("Misprediction: Bound read FB predicted: %d. Was: %d.\n",
   255                       predicted, actual);
   256         MOZ_ASSERT(false, "Read FB binding misprediction!");
   257     }
   258 #endif
   260     return mUserReadFB;
   261 }
   263 GLuint
   264 GLScreenBuffer::GetFB() const
   265 {
   266     MOZ_ASSERT(GetDrawFB() == GetReadFB());
   267     return GetDrawFB();
   268 }
   271 void
   272 GLScreenBuffer::DeletingFB(GLuint fb)
   273 {
   274     if (fb == mInternalDrawFB) {
   275         mInternalDrawFB = 0;
   276         mUserDrawFB = 0;
   277     }
   278     if (fb == mInternalReadFB) {
   279         mInternalReadFB = 0;
   280         mUserReadFB = 0;
   281     }
   282 }
   285 void
   286 GLScreenBuffer::AfterDrawCall()
   287 {
   288     if (mUserDrawFB != 0)
   289         return;
   291     RequireBlit();
   292 }
   294 void
   295 GLScreenBuffer::BeforeReadCall()
   296 {
   297     if (mUserReadFB != 0)
   298         return;
   300     AssureBlitted();
   301 }
   303 bool
   304 GLScreenBuffer::ReadPixels(GLint x, GLint y, GLsizei width, GLsizei height,
   305                            GLenum format, GLenum type, GLvoid *pixels)
   306 {
   307     // If the currently bound framebuffer is backed by a SharedSurface_GL
   308     // then it might want to override how we read pixel data from it.
   309     // This is normally only the default framebuffer, but we can also
   310     // have SharedSurfaces bound to other framebuffers when doing
   311     // readback for BasicLayers.
   312     SharedSurface_GL* surf;
   313     if (GetReadFB() == 0) {
   314         surf = SharedSurf();
   315     } else {
   316         surf = mGL->mFBOMapping[GetReadFB()];
   317     }
   318     if (surf) {
   319         return surf->ReadPixels(x, y, width, height, format, type, pixels);
   320     }
   322     return false;
   323 }
   325 void
   326 GLScreenBuffer::RequireBlit()
   327 {
   328     mNeedsBlit = true;
   329 }
   331 void
   332 GLScreenBuffer::AssureBlitted()
   333 {
   334     if (!mNeedsBlit)
   335         return;
   337     if (mDraw) {
   338         GLuint drawFB = DrawFB();
   339         GLuint readFB = ReadFB();
   341         MOZ_ASSERT(drawFB != 0);
   342         MOZ_ASSERT(drawFB != readFB);
   343         MOZ_ASSERT(mGL->IsSupported(GLFeature::framebuffer_blit));
   344         MOZ_ASSERT(mDraw->Size() == mRead->Size());
   346         ScopedBindFramebuffer boundFB(mGL);
   347         ScopedGLState scissor(mGL, LOCAL_GL_SCISSOR_TEST, false);
   349         BindReadFB_Internal(drawFB);
   350         BindDrawFB_Internal(readFB);
   352         const gfx::IntSize&  srcSize = mDraw->Size();
   353         const gfx::IntSize& destSize = mRead->Size();
   355         mGL->raw_fBlitFramebuffer(0, 0,  srcSize.width,  srcSize.height,
   356                                   0, 0, destSize.width, destSize.height,
   357                                   LOCAL_GL_COLOR_BUFFER_BIT,
   358                                   LOCAL_GL_NEAREST);
   359         // Done!
   360     }
   362     mNeedsBlit = false;
   363 }
   365 void
   366 GLScreenBuffer::Morph(SurfaceFactory_GL* newFactory, SurfaceStreamType streamType)
   367 {
   368     MOZ_ASSERT(mStream);
   370     if (newFactory) {
   371         delete mFactory;
   372         mFactory = newFactory;
   373     }
   375     if (mStream->mType == streamType)
   376         return;
   378     SurfaceStream* newStream = SurfaceStream::CreateForType(streamType, mGL, mStream);
   379     MOZ_ASSERT(newStream);
   381     mStream = newStream;
   382 }
   384 void
   385 GLScreenBuffer::Attach(SharedSurface* surface, const gfx::IntSize& size)
   386 {
   387     ScopedBindFramebuffer autoFB(mGL);
   389     SharedSurface_GL* surf = SharedSurface_GL::Cast(surface);
   390     if (mRead && SharedSurf())
   391         SharedSurf()->UnlockProd();
   393     surf->LockProd();
   395     if (mRead &&
   396         surf->AttachType() == SharedSurf()->AttachType() &&
   397         size == Size())
   398     {
   399         // Same size, same type, ready for reuse!
   400         mRead->Attach(surf);
   401     } else {
   402         // Else something changed, so resize:
   403         DrawBuffer* draw = CreateDraw(size);  // Can be null.
   404         ReadBuffer* read = CreateRead(surf);
   405         MOZ_ASSERT(read); // Should never fail if SwapProd succeeded.
   407         delete mDraw;
   408         delete mRead;
   410         mDraw = draw;
   411         mRead = read;
   412     }
   414     // Check that we're all set up.
   415     MOZ_ASSERT(SharedSurf() == surf);
   417     if (!PreserveBuffer()) {
   418         // DiscardFramebuffer here could help perf on some mobile platforms.
   419     }
   420 }
   422 bool
   423 GLScreenBuffer::Swap(const gfx::IntSize& size)
   424 {
   425     SharedSurface* nextSurf = mStream->SwapProducer(mFactory, size);
   426     if (!nextSurf) {
   427         SurfaceFactory_Basic basicFactory(mGL, mFactory->Caps());
   428         nextSurf = mStream->SwapProducer(&basicFactory, size);
   429         if (!nextSurf)
   430           return false;
   432         NS_WARNING("SwapProd failed for sophisticated Factory type, fell back to Basic.");
   433     }
   434     MOZ_ASSERT(nextSurf);
   436     Attach(nextSurf, size);
   438     return true;
   439 }
   441 bool
   442 GLScreenBuffer::PublishFrame(const gfx::IntSize& size)
   443 {
   444     AssureBlitted();
   446     bool good = Swap(size);
   447     return good;
   448 }
   450 bool
   451 GLScreenBuffer::Resize(const gfx::IntSize& size)
   452 {
   453     SharedSurface* surface = mStream->Resize(mFactory, size);
   454     if (!surface)
   455         return false;
   457     Attach(surface, size);
   458     return true;
   459 }
   461 DrawBuffer*
   462 GLScreenBuffer::CreateDraw(const gfx::IntSize& size)
   463 {
   464     GLContext* gl = mFactory->GL();
   465     const GLFormats& formats = mFactory->Formats();
   466     const SurfaceCaps& caps = mFactory->DrawCaps();
   468     return DrawBuffer::Create(gl, caps, formats, size);
   469 }
   471 ReadBuffer*
   472 GLScreenBuffer::CreateRead(SharedSurface_GL* surf)
   473 {
   474     GLContext* gl = mFactory->GL();
   475     const GLFormats& formats = mFactory->Formats();
   476     const SurfaceCaps& caps = mFactory->ReadCaps();
   478     return ReadBuffer::Create(gl, caps, formats, surf);
   479 }
   481 void
   482 GLScreenBuffer::Readback(SharedSurface_GL* src, DataSourceSurface* dest)
   483 {
   484   MOZ_ASSERT(src && dest);
   485   DataSourceSurface::MappedSurface ms;
   486   dest->Map(DataSourceSurface::MapType::READ, &ms);
   487   nsRefPtr<gfxImageSurface> wrappedDest =
   488     new gfxImageSurface(ms.mData,
   489                         ThebesIntSize(dest->GetSize()),
   490                         ms.mStride,
   491                         SurfaceFormatToImageFormat(dest->GetFormat()));
   492   DeprecatedReadback(src, wrappedDest);
   493   dest->Unmap();
   494 }
   496 void
   497 GLScreenBuffer::DeprecatedReadback(SharedSurface_GL* src, gfxImageSurface* dest)
   498 {
   499     MOZ_ASSERT(src && dest);
   500     MOZ_ASSERT(ToIntSize(dest->GetSize()) == src->Size());
   501     MOZ_ASSERT(dest->Format() == (src->HasAlpha() ? gfxImageFormat::ARGB32
   502                                                   : gfxImageFormat::RGB24));
   504     mGL->MakeCurrent();
   506     bool needsSwap = src != SharedSurf();
   507     if (needsSwap) {
   508         SharedSurf()->UnlockProd();
   509         src->LockProd();
   510     }
   512     ReadBuffer* buffer = CreateRead(src);
   513     MOZ_ASSERT(buffer);
   515     ScopedBindFramebuffer autoFB(mGL, buffer->FB());
   516     ReadPixelsIntoImageSurface(mGL, dest);
   518     delete buffer;
   520     if (needsSwap) {
   521         src->UnlockProd();
   522         SharedSurf()->LockProd();
   523     }
   524 }
   526 DrawBuffer*
   527 DrawBuffer::Create(GLContext* const gl,
   528                    const SurfaceCaps& caps,
   529                    const GLFormats& formats,
   530                    const gfx::IntSize& size)
   531 {
   532     if (!caps.color) {
   533         MOZ_ASSERT(!caps.alpha && !caps.depth && !caps.stencil);
   535         // Nothing is needed.
   536         return nullptr;
   537     }
   539     GLuint colorMSRB = 0;
   540     GLuint depthRB   = 0;
   541     GLuint stencilRB = 0;
   543     GLuint* pColorMSRB = caps.antialias ? &colorMSRB : nullptr;
   544     GLuint* pDepthRB   = caps.depth     ? &depthRB   : nullptr;
   545     GLuint* pStencilRB = caps.stencil   ? &stencilRB : nullptr;
   547     if (!formats.color_rbFormat)
   548         pColorMSRB = nullptr;
   550     if (pDepthRB && pStencilRB) {
   551         if (!formats.depth && !formats.depthStencil)
   552             pDepthRB = nullptr;
   554         if (!formats.stencil && !formats.depthStencil)
   555             pStencilRB = nullptr;
   556     } else {
   557         if (!formats.depth)
   558             pDepthRB = nullptr;
   560         if (!formats.stencil)
   561             pStencilRB = nullptr;
   562     }
   564     CreateRenderbuffersForOffscreen(gl, formats, size, caps.antialias,
   565                                     pColorMSRB, pDepthRB, pStencilRB);
   567     GLuint fb = 0;
   568     gl->fGenFramebuffers(1, &fb);
   569     gl->AttachBuffersToFB(0, colorMSRB, depthRB, stencilRB, fb);
   570     MOZ_ASSERT(gl->IsFramebufferComplete(fb));
   572     return new DrawBuffer(gl, size, fb, colorMSRB, depthRB, stencilRB);
   573 }
   575 DrawBuffer::~DrawBuffer()
   576 {
   577     mGL->MakeCurrent();
   579     GLuint fb = mFB;
   580     GLuint rbs[] = {
   581         mColorMSRB,
   582         mDepthRB,
   583         mStencilRB
   584     };
   586     mGL->fDeleteFramebuffers(1, &fb);
   587     mGL->fDeleteRenderbuffers(3, rbs);
   588 }
   595 ReadBuffer*
   596 ReadBuffer::Create(GLContext* gl,
   597                    const SurfaceCaps& caps,
   598                    const GLFormats& formats,
   599                    SharedSurface_GL* surf)
   600 {
   601     MOZ_ASSERT(surf);
   603     if (surf->AttachType() == AttachmentType::Screen) {
   604         // Don't need anything. Our read buffer will be the 'screen'.
   606         return new ReadBuffer(gl,
   607                               0, 0, 0,
   608                               surf);
   609     }
   611     GLuint depthRB = 0;
   612     GLuint stencilRB = 0;
   614     GLuint* pDepthRB   = caps.depth   ? &depthRB   : nullptr;
   615     GLuint* pStencilRB = caps.stencil ? &stencilRB : nullptr;
   617     CreateRenderbuffersForOffscreen(gl, formats, surf->Size(), caps.antialias,
   618                                     nullptr, pDepthRB, pStencilRB);
   620     GLuint colorTex = 0;
   621     GLuint colorRB = 0;
   622     GLenum target = 0;
   624     switch (surf->AttachType()) {
   625     case AttachmentType::GLTexture:
   626         colorTex = surf->ProdTexture();
   627         target = surf->ProdTextureTarget();
   628         break;
   629     case AttachmentType::GLRenderbuffer:
   630         colorRB = surf->ProdRenderbuffer();
   631         break;
   632     default:
   633         MOZ_CRASH("Unknown attachment type?");
   634     }
   635     MOZ_ASSERT(colorTex || colorRB);
   637     GLuint fb = 0;
   638     gl->fGenFramebuffers(1, &fb);
   639     gl->AttachBuffersToFB(colorTex, colorRB, depthRB, stencilRB, fb, target);
   640     gl->mFBOMapping[fb] = surf;
   642     MOZ_ASSERT(gl->IsFramebufferComplete(fb));
   644     return new ReadBuffer(gl,
   645                           fb, depthRB, stencilRB,
   646                           surf);
   647 }
   649 ReadBuffer::~ReadBuffer()
   650 {
   651     mGL->MakeCurrent();
   653     GLuint fb = mFB;
   654     GLuint rbs[] = {
   655         mDepthRB,
   656         mStencilRB
   657     };
   659     mGL->fDeleteFramebuffers(1, &fb);
   660     mGL->fDeleteRenderbuffers(2, rbs);
   661     mGL->mFBOMapping.erase(mFB);
   662 }
   664 void
   665 ReadBuffer::Attach(SharedSurface_GL* surf)
   666 {
   667     MOZ_ASSERT(surf && mSurf);
   668     MOZ_ASSERT(surf->AttachType() == mSurf->AttachType());
   669     MOZ_ASSERT(surf->Size() == mSurf->Size());
   671     // Nothing else is needed for AttachType Screen.
   672     if (surf->AttachType() != AttachmentType::Screen) {
   673         GLuint colorTex = 0;
   674         GLuint colorRB = 0;
   675         GLenum target = 0;
   677         switch (surf->AttachType()) {
   678         case AttachmentType::GLTexture:
   679             colorTex = surf->ProdTexture();
   680             target = surf->ProdTextureTarget();
   681             break;
   682         case AttachmentType::GLRenderbuffer:
   683             colorRB = surf->ProdRenderbuffer();
   684             break;
   685         default:
   686             MOZ_CRASH("Unknown attachment type?");
   687         }
   689         mGL->AttachBuffersToFB(colorTex, colorRB, 0, 0, mFB, target);
   690         mGL->mFBOMapping[mFB] = surf;
   691         MOZ_ASSERT(mGL->IsFramebufferComplete(mFB));
   692     }
   694     mSurf = surf;
   695 }
   697 const gfx::IntSize&
   698 ReadBuffer::Size() const
   699 {
   700     return mSurf->Size();
   701 }
   703 } /* namespace gl */
   704 } /* namespace mozilla */

mercurial