gfx/angle/src/libGLESv2/Framebuffer.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
-rw-r--r--

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 #include "precompiled.h"
     2 //
     3 // Copyright (c) 2002-2013 The ANGLE Project Authors. All rights reserved.
     4 // Use of this source code is governed by a BSD-style license that can be
     5 // found in the LICENSE file.
     6 //
     8 // Framebuffer.cpp: Implements the gl::Framebuffer class. Implements GL framebuffer
     9 // objects and related functionality. [OpenGL ES 2.0.24] section 4.4 page 105.
    11 #include "libGLESv2/Framebuffer.h"
    13 #include "libGLESv2/main.h"
    14 #include "libGLESv2/utilities.h"
    15 #include "libGLESv2/Texture.h"
    16 #include "libGLESv2/Context.h"
    17 #include "libGLESv2/renderer/Renderer.h"
    18 #include "libGLESv2/Renderbuffer.h"
    20 namespace gl
    21 {
    23 Framebuffer::Framebuffer(rx::Renderer *renderer)
    24     : mRenderer(renderer)
    25 {
    26     for (unsigned int colorAttachment = 0; colorAttachment < IMPLEMENTATION_MAX_DRAW_BUFFERS; colorAttachment++)
    27     {
    28         mColorbufferTypes[colorAttachment] = GL_NONE;
    29         mDrawBufferStates[colorAttachment] = GL_NONE;
    30     }
    31     mDrawBufferStates[0] = GL_COLOR_ATTACHMENT0_EXT;
    32     mReadBufferState = GL_COLOR_ATTACHMENT0_EXT;
    34     mDepthbufferType = GL_NONE;
    35     mStencilbufferType = GL_NONE;
    36 }
    38 Framebuffer::~Framebuffer()
    39 {
    40     for (unsigned int colorAttachment = 0; colorAttachment < IMPLEMENTATION_MAX_DRAW_BUFFERS; colorAttachment++)
    41     {
    42         mColorbufferPointers[colorAttachment].set(NULL);
    43     }
    44     mDepthbufferPointer.set(NULL);
    45     mStencilbufferPointer.set(NULL);
    46 }
    48 Renderbuffer *Framebuffer::lookupRenderbuffer(GLenum type, GLuint handle) const
    49 {
    50     gl::Context *context = gl::getContext();
    51     Renderbuffer *buffer = NULL;
    53     if (type == GL_NONE)
    54     {
    55         buffer = NULL;
    56     }
    57     else if (type == GL_RENDERBUFFER)
    58     {
    59         buffer = context->getRenderbuffer(handle);
    60     }
    61     else if (IsInternalTextureTarget(type))
    62     {
    63         buffer = context->getTexture(handle)->getRenderbuffer(type);
    64     }
    65     else
    66     {
    67         UNREACHABLE();
    68     }
    70     return buffer;
    71 }
    73 void Framebuffer::setColorbuffer(unsigned int colorAttachment, GLenum type, GLuint colorbuffer)
    74 {
    75     ASSERT(colorAttachment < IMPLEMENTATION_MAX_DRAW_BUFFERS);
    76     mColorbufferTypes[colorAttachment] = (colorbuffer != 0) ? type : GL_NONE;
    77     mColorbufferPointers[colorAttachment].set(lookupRenderbuffer(type, colorbuffer));
    78 }
    80 void Framebuffer::setDepthbuffer(GLenum type, GLuint depthbuffer)
    81 {
    82     mDepthbufferType = (depthbuffer != 0) ? type : GL_NONE;
    83     mDepthbufferPointer.set(lookupRenderbuffer(type, depthbuffer));
    84 }
    86 void Framebuffer::setStencilbuffer(GLenum type, GLuint stencilbuffer)
    87 {
    88     mStencilbufferType = (stencilbuffer != 0) ? type : GL_NONE;
    89     mStencilbufferPointer.set(lookupRenderbuffer(type, stencilbuffer));
    90 }
    92 void Framebuffer::detachTexture(GLuint texture)
    93 {
    94     for (unsigned int colorAttachment = 0; colorAttachment < IMPLEMENTATION_MAX_DRAW_BUFFERS; colorAttachment++)
    95     {
    96         if (mColorbufferPointers[colorAttachment].id() == texture && IsInternalTextureTarget(mColorbufferTypes[colorAttachment]))
    97         {
    98             mColorbufferTypes[colorAttachment] = GL_NONE;
    99             mColorbufferPointers[colorAttachment].set(NULL);
   100         }
   101     }
   103     if (mDepthbufferPointer.id() == texture && IsInternalTextureTarget(mDepthbufferType))
   104     {
   105         mDepthbufferType = GL_NONE;
   106         mDepthbufferPointer.set(NULL);
   107     }
   109     if (mStencilbufferPointer.id() == texture && IsInternalTextureTarget(mStencilbufferType))
   110     {
   111         mStencilbufferType = GL_NONE;
   112         mStencilbufferPointer.set(NULL);
   113     }
   114 }
   116 void Framebuffer::detachRenderbuffer(GLuint renderbuffer)
   117 {
   118     for (unsigned int colorAttachment = 0; colorAttachment < IMPLEMENTATION_MAX_DRAW_BUFFERS; colorAttachment++)
   119     {
   120         if (mColorbufferPointers[colorAttachment].id() == renderbuffer && mColorbufferTypes[colorAttachment] == GL_RENDERBUFFER)
   121         {
   122             mColorbufferTypes[colorAttachment] = GL_NONE;
   123             mColorbufferPointers[colorAttachment].set(NULL);
   124         }
   125     }
   127     if (mDepthbufferPointer.id() == renderbuffer && mDepthbufferType == GL_RENDERBUFFER)
   128     {
   129         mDepthbufferType = GL_NONE;
   130         mDepthbufferPointer.set(NULL);
   131     }
   133     if (mStencilbufferPointer.id() == renderbuffer && mStencilbufferType == GL_RENDERBUFFER)
   134     {
   135         mStencilbufferType = GL_NONE;
   136         mStencilbufferPointer.set(NULL);
   137     }
   138 }
   140 unsigned int Framebuffer::getRenderTargetSerial(unsigned int colorAttachment) const
   141 {
   142     ASSERT(colorAttachment < IMPLEMENTATION_MAX_DRAW_BUFFERS);
   144     Renderbuffer *colorbuffer = mColorbufferPointers[colorAttachment].get();
   146     if (colorbuffer)
   147     {
   148         return colorbuffer->getSerial();
   149     }
   151     return 0;
   152 }
   154 unsigned int Framebuffer::getDepthbufferSerial() const
   155 {
   156     Renderbuffer *depthbuffer = mDepthbufferPointer.get();
   158     if (depthbuffer)
   159     {
   160         return depthbuffer->getSerial();
   161     }
   163     return 0;
   164 }
   166 unsigned int Framebuffer::getStencilbufferSerial() const
   167 {
   168     Renderbuffer *stencilbuffer = mStencilbufferPointer.get();
   170     if (stencilbuffer)
   171     {
   172         return stencilbuffer->getSerial();
   173     }
   175     return 0;
   176 }
   178 Renderbuffer *Framebuffer::getColorbuffer(unsigned int colorAttachment) const
   179 {
   180     ASSERT(colorAttachment < IMPLEMENTATION_MAX_DRAW_BUFFERS);
   181     return mColorbufferPointers[colorAttachment].get();
   182 }
   184 Renderbuffer *Framebuffer::getDepthbuffer() const
   185 {
   186     return mDepthbufferPointer.get();
   187 }
   189 Renderbuffer *Framebuffer::getStencilbuffer() const
   190 {
   191     return mStencilbufferPointer.get();
   192 }
   194 Renderbuffer *Framebuffer::getDepthOrStencilbuffer() const
   195 {
   196     Renderbuffer *depthstencilbuffer = mDepthbufferPointer.get();
   198     if (!depthstencilbuffer)
   199     {
   200         depthstencilbuffer = mStencilbufferPointer.get();
   201     }
   203     return depthstencilbuffer;
   204 }
   206 Renderbuffer *Framebuffer::getReadColorbuffer() const
   207 {
   208     // Will require more logic if glReadBuffers is supported
   209     return mColorbufferPointers[0].get();
   210 }
   212 GLenum Framebuffer::getReadColorbufferType() const
   213 {
   214     // Will require more logic if glReadBuffers is supported
   215     return mColorbufferTypes[0];
   216 }
   218 Renderbuffer *Framebuffer::getFirstColorbuffer() const
   219 {
   220     for (unsigned int colorAttachment = 0; colorAttachment < IMPLEMENTATION_MAX_DRAW_BUFFERS; colorAttachment++)
   221     {
   222         if (mColorbufferTypes[colorAttachment] != GL_NONE)
   223         {
   224             return mColorbufferPointers[colorAttachment].get();
   225         }
   226     }
   228     return NULL;
   229 }
   231 GLenum Framebuffer::getColorbufferType(unsigned int colorAttachment) const
   232 {
   233     ASSERT(colorAttachment < IMPLEMENTATION_MAX_DRAW_BUFFERS);
   234     return mColorbufferTypes[colorAttachment];
   235 }
   237 GLenum Framebuffer::getDepthbufferType() const
   238 {
   239     return mDepthbufferType;
   240 }
   242 GLenum Framebuffer::getStencilbufferType() const
   243 {
   244     return mStencilbufferType;
   245 }
   247 GLuint Framebuffer::getColorbufferHandle(unsigned int colorAttachment) const
   248 {
   249     ASSERT(colorAttachment < IMPLEMENTATION_MAX_DRAW_BUFFERS);
   250     return mColorbufferPointers[colorAttachment].id();
   251 }
   253 GLuint Framebuffer::getDepthbufferHandle() const
   254 {
   255     return mDepthbufferPointer.id();
   256 }
   258 GLuint Framebuffer::getStencilbufferHandle() const
   259 {
   260     return mStencilbufferPointer.id();
   261 }
   263 GLenum Framebuffer::getDrawBufferState(unsigned int colorAttachment) const
   264 {
   265     return mDrawBufferStates[colorAttachment];
   266 }
   268 void Framebuffer::setDrawBufferState(unsigned int colorAttachment, GLenum drawBuffer)
   269 {
   270     mDrawBufferStates[colorAttachment] = drawBuffer;
   271 }
   273 bool Framebuffer::isEnabledColorAttachment(unsigned int colorAttachment) const
   274 {
   275     return (mColorbufferTypes[colorAttachment] != GL_NONE && mDrawBufferStates[colorAttachment] != GL_NONE);
   276 }
   278 bool Framebuffer::hasEnabledColorAttachment() const
   279 {
   280     for (unsigned int colorAttachment = 0; colorAttachment < gl::IMPLEMENTATION_MAX_DRAW_BUFFERS; colorAttachment++)
   281     {
   282         if (isEnabledColorAttachment(colorAttachment))
   283         {
   284             return true;
   285         }
   286     }
   288     return false;
   289 }
   291 bool Framebuffer::hasStencil() const
   292 {
   293     if (mStencilbufferType != GL_NONE)
   294     {
   295         const Renderbuffer *stencilbufferObject = getStencilbuffer();
   297         if (stencilbufferObject)
   298         {
   299             return stencilbufferObject->getStencilSize() > 0;
   300         }
   301     }
   303     return false;
   304 }
   306 bool Framebuffer::usingExtendedDrawBuffers() const
   307 {
   308     for (unsigned int colorAttachment = 1; colorAttachment < IMPLEMENTATION_MAX_DRAW_BUFFERS; colorAttachment++)
   309     {
   310         if (isEnabledColorAttachment(colorAttachment))
   311         {
   312             return true;
   313         }
   314     }
   316     return false;
   317 }
   319 GLenum Framebuffer::completeness() const
   320 {
   321     int width = 0;
   322     int height = 0;
   323     int colorbufferSize = 0;
   324     int samples = -1;
   325     bool missingAttachment = true;
   327     for (unsigned int colorAttachment = 0; colorAttachment < IMPLEMENTATION_MAX_DRAW_BUFFERS; colorAttachment++)
   328     {
   329         if (mColorbufferTypes[colorAttachment] != GL_NONE)
   330         {
   331             const Renderbuffer *colorbuffer = getColorbuffer(colorAttachment);
   333             if (!colorbuffer)
   334             {
   335                 return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
   336             }
   338             if (colorbuffer->getWidth() == 0 || colorbuffer->getHeight() == 0)
   339             {
   340                 return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
   341             }
   343             if (mColorbufferTypes[colorAttachment] == GL_RENDERBUFFER)
   344             {
   345                 if (!gl::IsColorRenderable(colorbuffer->getInternalFormat()))
   346                 {
   347                     return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
   348                 }
   349             }
   350             else if (IsInternalTextureTarget(mColorbufferTypes[colorAttachment]))
   351             {
   352                 GLint internalformat = colorbuffer->getInternalFormat();
   353                 GLenum format = gl::ExtractFormat(internalformat);
   355                 if (IsCompressed(format) ||
   356                     format == GL_ALPHA ||
   357                     format == GL_LUMINANCE ||
   358                     format == GL_LUMINANCE_ALPHA)
   359                 {
   360                     return GL_FRAMEBUFFER_UNSUPPORTED;
   361                 }
   363                 bool filtering, renderable;
   365                 if ((gl::IsFloat32Format(internalformat) && !mRenderer->getFloat32TextureSupport(&filtering, &renderable)) ||
   366                     (gl::IsFloat16Format(internalformat) && !mRenderer->getFloat16TextureSupport(&filtering, &renderable)))
   367                 {
   368                     return GL_FRAMEBUFFER_UNSUPPORTED;
   369                 }
   371                 if (gl::IsDepthTexture(internalformat) || gl::IsStencilTexture(internalformat))
   372                 {
   373                     return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
   374                 }
   375             }
   376             else
   377             {
   378                 UNREACHABLE();
   379                 return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
   380             }
   382             if (!missingAttachment)
   383             {
   384                 // all color attachments must have the same width and height
   385                 if (colorbuffer->getWidth() != width || colorbuffer->getHeight() != height)
   386                 {
   387                     return GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS;
   388                 }
   390                 // APPLE_framebuffer_multisample, which EXT_draw_buffers refers to, requires that
   391                 // all color attachments have the same number of samples for the FBO to be complete.
   392                 if (colorbuffer->getSamples() != samples)
   393                 {
   394                     return GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_EXT;
   395                 }
   397                 // all color attachments attachments must have the same number of bitplanes
   398                 if (gl::ComputePixelSize(colorbuffer->getInternalFormat()) != colorbufferSize)
   399                 {
   400                     return GL_FRAMEBUFFER_UNSUPPORTED;
   401                 }
   403                 // D3D11 does not allow for overlapping RenderTargetViews, so ensure uniqueness
   404                 for (unsigned int previousColorAttachment = 0; previousColorAttachment < colorAttachment; previousColorAttachment++)
   405                 {
   406                     if (mColorbufferPointers[colorAttachment].get() == mColorbufferPointers[previousColorAttachment].get())
   407                     {
   408                         return GL_FRAMEBUFFER_UNSUPPORTED;
   409                     }
   410                 }
   411             }
   412             else
   413             {
   414                 width = colorbuffer->getWidth();
   415                 height = colorbuffer->getHeight();
   416                 samples = colorbuffer->getSamples();
   417                 colorbufferSize = gl::ComputePixelSize(colorbuffer->getInternalFormat());
   418                 missingAttachment = false;
   419             }
   420         }
   421     }
   423     const Renderbuffer *depthbuffer = NULL;
   424     const Renderbuffer *stencilbuffer = NULL;
   426     if (mDepthbufferType != GL_NONE)
   427     {
   428         depthbuffer = getDepthbuffer();
   430         if (!depthbuffer)
   431         {
   432             return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
   433         }
   435         if (depthbuffer->getWidth() == 0 || depthbuffer->getHeight() == 0)
   436         {
   437             return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
   438         }
   440         if (mDepthbufferType == GL_RENDERBUFFER)
   441         {
   442             if (!gl::IsDepthRenderable(depthbuffer->getInternalFormat()))
   443             {
   444                 return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
   445             }
   446         }
   447         else if (IsInternalTextureTarget(mDepthbufferType))
   448         {
   449             GLint internalformat = depthbuffer->getInternalFormat();
   451             // depth texture attachments require OES/ANGLE_depth_texture
   452             if (!mRenderer->getDepthTextureSupport())
   453             {
   454                 return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
   455             }
   457             if (!gl::IsDepthTexture(internalformat))
   458             {
   459                 return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
   460             }
   461         }
   462         else
   463         {
   464             UNREACHABLE();
   465             return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
   466         }
   468         if (missingAttachment)
   469         {
   470             width = depthbuffer->getWidth();
   471             height = depthbuffer->getHeight();
   472             samples = depthbuffer->getSamples();
   473             missingAttachment = false;
   474         }
   475         else if (width != depthbuffer->getWidth() || height != depthbuffer->getHeight())
   476         {
   477             return GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS;
   478         }
   479         else if (samples != depthbuffer->getSamples())
   480         {
   481             return GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_ANGLE;
   482         }
   483     }
   485     if (mStencilbufferType != GL_NONE)
   486     {
   487         stencilbuffer = getStencilbuffer();
   489         if (!stencilbuffer)
   490         {
   491             return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
   492         }
   494         if (stencilbuffer->getWidth() == 0 || stencilbuffer->getHeight() == 0)
   495         {
   496             return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
   497         }
   499         if (mStencilbufferType == GL_RENDERBUFFER)
   500         {
   501             if (!gl::IsStencilRenderable(stencilbuffer->getInternalFormat()))
   502             {
   503                 return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
   504             }
   505         }
   506         else if (IsInternalTextureTarget(mStencilbufferType))
   507         {
   508             GLint internalformat = stencilbuffer->getInternalFormat();
   510             // texture stencil attachments come along as part
   511             // of OES_packed_depth_stencil + OES/ANGLE_depth_texture
   512             if (!mRenderer->getDepthTextureSupport())
   513             {
   514                 return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
   515             }
   517             if (!gl::IsStencilTexture(internalformat))
   518             {
   519                 return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
   520             }
   521         }
   522         else
   523         {
   524             UNREACHABLE();
   525             return GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT;
   526         }
   528         if (missingAttachment)
   529         {
   530             width = stencilbuffer->getWidth();
   531             height = stencilbuffer->getHeight();
   532             samples = stencilbuffer->getSamples();
   533             missingAttachment = false;
   534         }
   535         else if (width != stencilbuffer->getWidth() || height != stencilbuffer->getHeight())
   536         {
   537             return GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS;
   538         }
   539         else if (samples != stencilbuffer->getSamples())
   540         {
   541             return GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_ANGLE;
   542         }
   543     }
   545     // if we have both a depth and stencil buffer, they must refer to the same object
   546     // since we only support packed_depth_stencil and not separate depth and stencil
   547     if (depthbuffer && stencilbuffer && (depthbuffer != stencilbuffer))
   548     {
   549         return GL_FRAMEBUFFER_UNSUPPORTED;
   550     }
   552     // we need to have at least one attachment to be complete
   553     if (missingAttachment)
   554     {
   555         return GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT;
   556     }
   558     return GL_FRAMEBUFFER_COMPLETE;
   559 }
   561 DefaultFramebuffer::DefaultFramebuffer(rx::Renderer *renderer, Colorbuffer *colorbuffer, DepthStencilbuffer *depthStencil)
   562     : Framebuffer(renderer)
   563 {
   564     mColorbufferPointers[0].set(new Renderbuffer(mRenderer, 0, colorbuffer));
   566     Renderbuffer *depthStencilRenderbuffer = new Renderbuffer(mRenderer, 0, depthStencil);
   567     mDepthbufferPointer.set(depthStencilRenderbuffer);
   568     mStencilbufferPointer.set(depthStencilRenderbuffer);
   570     mColorbufferTypes[0] = GL_RENDERBUFFER;
   571     mDepthbufferType = (depthStencilRenderbuffer->getDepthSize() != 0) ? GL_RENDERBUFFER : GL_NONE;
   572     mStencilbufferType = (depthStencilRenderbuffer->getStencilSize() != 0) ? GL_RENDERBUFFER : GL_NONE;
   574     mDrawBufferStates[0] = GL_BACK;
   575     mReadBufferState = GL_BACK;
   576 }
   578 int Framebuffer::getSamples() const
   579 {
   580     if (completeness() == GL_FRAMEBUFFER_COMPLETE)
   581     {
   582         // for a complete framebuffer, all attachments must have the same sample count
   583         // in this case return the first nonzero sample size
   584         for (unsigned int colorAttachment = 0; colorAttachment < IMPLEMENTATION_MAX_DRAW_BUFFERS; colorAttachment++)
   585         {
   586             if (mColorbufferTypes[colorAttachment] != GL_NONE)
   587             {
   588                 return getColorbuffer(colorAttachment)->getSamples();
   589             }
   590         }
   591     }
   593     return 0;
   594 }
   596 GLenum DefaultFramebuffer::completeness() const
   597 {
   598     // The default framebuffer *must* always be complete, though it may not be
   599     // subject to the same rules as application FBOs. ie, it could have 0x0 size.
   600     return GL_FRAMEBUFFER_COMPLETE;
   601 }
   603 }

mercurial