LCOV - code coverage report
Current view: top level - dom/canvas - WebGLRenderbuffer.cpp (source / functions) Hit Total Coverage
Test: output.info Lines: 0 142 0.0 %
Date: 2017-07-14 16:53:18 Functions: 0 17 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       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/. */
       5             : 
       6             : #include "WebGLRenderbuffer.h"
       7             : 
       8             : #include "GLContext.h"
       9             : #include "mozilla/dom/WebGLRenderingContextBinding.h"
      10             : #include "ScopedGLHelpers.h"
      11             : #include "WebGLContext.h"
      12             : #include "WebGLStrongTypes.h"
      13             : #include "WebGLTexture.h"
      14             : 
      15             : namespace mozilla {
      16             : 
      17             : static GLenum
      18           0 : DepthFormatForDepthStencilEmu(gl::GLContext* gl)
      19             : {
      20             :     // We might not be able to get 24-bit, so let's pretend!
      21           0 :     if (gl->IsGLES() && !gl->IsExtensionSupported(gl::GLContext::OES_depth24))
      22           0 :         return LOCAL_GL_DEPTH_COMPONENT16;
      23             : 
      24           0 :     return LOCAL_GL_DEPTH_COMPONENT24;
      25             : }
      26             : 
      27             : JSObject*
      28           0 : WebGLRenderbuffer::WrapObject(JSContext* cx, JS::Handle<JSObject*> givenProto)
      29             : {
      30           0 :     return dom::WebGLRenderbufferBinding::Wrap(cx, this, givenProto);
      31             : }
      32             : 
      33             : static GLuint
      34           0 : DoCreateRenderbuffer(gl::GLContext* gl)
      35             : {
      36           0 :     MOZ_ASSERT(gl->IsCurrent());
      37             : 
      38           0 :     GLuint ret = 0;
      39           0 :     gl->fGenRenderbuffers(1, &ret);
      40           0 :     return ret;
      41             : }
      42             : 
      43             : static bool
      44           0 : EmulatePackedDepthStencil(gl::GLContext* gl)
      45             : {
      46           0 :     return !gl->IsSupported(gl::GLFeature::packed_depth_stencil);
      47             : }
      48             : 
      49           0 : WebGLRenderbuffer::WebGLRenderbuffer(WebGLContext* webgl)
      50             :     : WebGLRefCountedObject(webgl)
      51           0 :     , mPrimaryRB( DoCreateRenderbuffer(webgl->gl) )
      52           0 :     , mEmulatePackedDepthStencil( EmulatePackedDepthStencil(webgl->gl) )
      53             :     , mSecondaryRB(0)
      54             :     , mFormat(nullptr)
      55             :     , mSamples(0)
      56             :     , mImageDataStatus(WebGLImageDataStatus::NoImageData)
      57           0 :     , mHasBeenBound(false)
      58             : {
      59           0 :     mContext->mRenderbuffers.insertBack(this);
      60           0 : }
      61             : 
      62             : void
      63           0 : WebGLRenderbuffer::Delete()
      64             : {
      65           0 :     mContext->MakeContextCurrent();
      66             : 
      67           0 :     mContext->gl->fDeleteRenderbuffers(1, &mPrimaryRB);
      68           0 :     if (mSecondaryRB)
      69           0 :         mContext->gl->fDeleteRenderbuffers(1, &mSecondaryRB);
      70             : 
      71           0 :     LinkedListElement<WebGLRenderbuffer>::removeFrom(mContext->mRenderbuffers);
      72           0 : }
      73             : 
      74             : int64_t
      75           0 : WebGLRenderbuffer::MemoryUsage() const
      76             : {
      77             :     // If there is no defined format, we're not taking up any memory
      78           0 :     if (!mFormat)
      79           0 :         return 0;
      80             : 
      81           0 :     const auto bytesPerPixel = mFormat->format->estimatedBytesPerPixel;
      82           0 :     const int64_t pixels = int64_t(mWidth) * int64_t(mHeight);
      83             : 
      84           0 :     const int64_t totalSize = pixels * bytesPerPixel;
      85           0 :     return totalSize;
      86             : }
      87             : 
      88             : static GLenum
      89           0 : DoRenderbufferStorageMaybeMultisample(gl::GLContext* gl, GLsizei samples,
      90             :                                       GLenum internalFormat, GLsizei width,
      91             :                                       GLsizei height)
      92             : {
      93           0 :     MOZ_ASSERT_IF(samples >= 1, gl->IsSupported(gl::GLFeature::framebuffer_multisample));
      94             : 
      95             :     // Certain OpenGL ES renderbuffer formats may not exist on desktop OpenGL.
      96           0 :     switch (internalFormat) {
      97             :     case LOCAL_GL_RGBA4:
      98             :     case LOCAL_GL_RGB5_A1:
      99             :         // 16-bit RGBA formats are not supported on desktop GL.
     100           0 :         if (!gl->IsGLES())
     101           0 :             internalFormat = LOCAL_GL_RGBA8;
     102           0 :         break;
     103             : 
     104             :     case LOCAL_GL_RGB565:
     105             :         // RGB565 is not supported on desktop GL.
     106           0 :         if (!gl->IsGLES())
     107           0 :             internalFormat = LOCAL_GL_RGB8;
     108           0 :         break;
     109             : 
     110             :     case LOCAL_GL_DEPTH_COMPONENT16:
     111           0 :         if (!gl->IsGLES() || gl->IsExtensionSupported(gl::GLContext::OES_depth24))
     112           0 :             internalFormat = LOCAL_GL_DEPTH_COMPONENT24;
     113           0 :         else if (gl->IsSupported(gl::GLFeature::packed_depth_stencil))
     114           0 :             internalFormat = LOCAL_GL_DEPTH24_STENCIL8;
     115           0 :         break;
     116             : 
     117             :     case LOCAL_GL_DEPTH_STENCIL:
     118           0 :         MOZ_CRASH("GFX: GL_DEPTH_STENCIL is not valid here.");
     119             :         break;
     120             : 
     121             :     default:
     122           0 :         break;
     123             :     }
     124             : 
     125           0 :     gl::GLContext::LocalErrorScope errorScope(*gl);
     126             : 
     127           0 :     if (samples > 0) {
     128             :         gl->fRenderbufferStorageMultisample(LOCAL_GL_RENDERBUFFER, samples,
     129           0 :                                             internalFormat, width, height);
     130             :     } else {
     131           0 :         gl->fRenderbufferStorage(LOCAL_GL_RENDERBUFFER, internalFormat, width, height);
     132             :     }
     133             : 
     134           0 :     return errorScope.GetError();
     135             : }
     136             : 
     137             : GLenum
     138           0 : WebGLRenderbuffer::DoRenderbufferStorage(uint32_t samples,
     139             :                                          const webgl::FormatUsageInfo* format,
     140             :                                          uint32_t width, uint32_t height)
     141             : {
     142           0 :     MOZ_ASSERT(mContext->mBoundRenderbuffer == this);
     143             : 
     144           0 :     gl::GLContext* gl = mContext->gl;
     145           0 :     MOZ_ASSERT(samples <= 256); // Sanity check.
     146             : 
     147           0 :     GLenum primaryFormat = format->format->sizedFormat;
     148           0 :     GLenum secondaryFormat = 0;
     149             : 
     150           0 :     if (mEmulatePackedDepthStencil && primaryFormat == LOCAL_GL_DEPTH24_STENCIL8) {
     151           0 :         primaryFormat = DepthFormatForDepthStencilEmu(gl);
     152           0 :         secondaryFormat = LOCAL_GL_STENCIL_INDEX8;
     153             :     }
     154             : 
     155           0 :     gl->fBindRenderbuffer(LOCAL_GL_RENDERBUFFER, mPrimaryRB);
     156           0 :     GLenum error = DoRenderbufferStorageMaybeMultisample(gl, samples, primaryFormat,
     157           0 :                                                          width, height);
     158           0 :     if (error)
     159           0 :         return error;
     160             : 
     161           0 :     if (secondaryFormat) {
     162           0 :         if (!mSecondaryRB) {
     163           0 :             gl->fGenRenderbuffers(1, &mSecondaryRB);
     164             :         }
     165             : 
     166           0 :         gl->fBindRenderbuffer(LOCAL_GL_RENDERBUFFER, mSecondaryRB);
     167           0 :         error = DoRenderbufferStorageMaybeMultisample(gl, samples, secondaryFormat,
     168           0 :                                                       width, height);
     169           0 :         if (error)
     170           0 :             return error;
     171           0 :     } else if (mSecondaryRB) {
     172           0 :         gl->fDeleteRenderbuffers(1, &mSecondaryRB);
     173           0 :         mSecondaryRB = 0;
     174             :     }
     175             : 
     176           0 :     return 0;
     177             : }
     178             : 
     179             : void
     180           0 : WebGLRenderbuffer::RenderbufferStorage(const char* funcName, uint32_t samples,
     181             :                                        GLenum internalFormat, uint32_t width,
     182             :                                        uint32_t height)
     183             : {
     184           0 :     const auto usage = mContext->mFormatUsage->GetRBUsage(internalFormat);
     185           0 :     if (!usage) {
     186           0 :         mContext->ErrorInvalidEnum("%s: Invalid `internalFormat`: 0x%04x.", funcName,
     187           0 :                                    internalFormat);
     188           0 :         return;
     189             :     }
     190             : 
     191           0 :     if (width > mContext->mImplMaxRenderbufferSize ||
     192           0 :         height > mContext->mImplMaxRenderbufferSize)
     193             :     {
     194           0 :         mContext->ErrorInvalidValue("%s: Width or height exceeds maximum renderbuffer"
     195             :                                     " size.",
     196           0 :                                     funcName);
     197           0 :         return;
     198             :     }
     199             : 
     200           0 :     mContext->MakeContextCurrent();
     201             : 
     202           0 :     if (!usage->maxSamplesKnown) {
     203           0 :         const_cast<webgl::FormatUsageInfo*>(usage)->ResolveMaxSamples(mContext->gl);
     204             :     }
     205           0 :     MOZ_ASSERT(usage->maxSamplesKnown);
     206             : 
     207           0 :     if (samples > usage->maxSamples) {
     208           0 :         mContext->ErrorInvalidOperation("%s: `samples` is out of the valid range.", funcName);
     209           0 :         return;
     210             :     }
     211             : 
     212             :     // Validation complete.
     213             : 
     214           0 :     const GLenum error = DoRenderbufferStorage(samples, usage, width, height);
     215           0 :     if (error) {
     216           0 :         const char* errorName = mContext->ErrorName(error);
     217           0 :         mContext->GenerateWarning("%s generated error %s", funcName, errorName);
     218           0 :         return;
     219             :     }
     220             : 
     221           0 :     mSamples = samples;
     222           0 :     mFormat = usage;
     223           0 :     mWidth = width;
     224           0 :     mHeight = height;
     225           0 :     mImageDataStatus = WebGLImageDataStatus::UninitializedImageData;
     226             : 
     227           0 :     InvalidateStatusOfAttachedFBs(funcName);
     228             : }
     229             : 
     230             : void
     231           0 : WebGLRenderbuffer::DoFramebufferRenderbuffer(FBTarget target, GLenum attachment) const
     232             : {
     233           0 :     gl::GLContext* gl = mContext->gl;
     234             : 
     235           0 :     if (attachment == LOCAL_GL_DEPTH_STENCIL_ATTACHMENT) {
     236           0 :         const GLuint stencilRB = (mSecondaryRB ? mSecondaryRB : mPrimaryRB);
     237           0 :         gl->fFramebufferRenderbuffer(target.get(), LOCAL_GL_DEPTH_ATTACHMENT,
     238           0 :                                      LOCAL_GL_RENDERBUFFER, mPrimaryRB);
     239           0 :         gl->fFramebufferRenderbuffer(target.get(), LOCAL_GL_STENCIL_ATTACHMENT,
     240           0 :                                      LOCAL_GL_RENDERBUFFER, stencilRB);
     241           0 :         return;
     242             :     }
     243             : 
     244           0 :     gl->fFramebufferRenderbuffer(target.get(), attachment,
     245           0 :                                  LOCAL_GL_RENDERBUFFER, mPrimaryRB);
     246             : }
     247             : 
     248             : GLint
     249           0 : WebGLRenderbuffer::GetRenderbufferParameter(RBTarget target,
     250             :                                             RBParam pname) const
     251             : {
     252           0 :     gl::GLContext* gl = mContext->gl;
     253             : 
     254           0 :     switch (pname.get()) {
     255             :     case LOCAL_GL_RENDERBUFFER_STENCIL_SIZE:
     256           0 :         if (!mFormat)
     257           0 :             return 0;
     258             : 
     259           0 :         if (!mFormat->format->s)
     260           0 :             return 0;
     261             : 
     262           0 :         return 8;
     263             : 
     264             :     case LOCAL_GL_RENDERBUFFER_SAMPLES:
     265             :     case LOCAL_GL_RENDERBUFFER_WIDTH:
     266             :     case LOCAL_GL_RENDERBUFFER_HEIGHT:
     267             :     case LOCAL_GL_RENDERBUFFER_RED_SIZE:
     268             :     case LOCAL_GL_RENDERBUFFER_GREEN_SIZE:
     269             :     case LOCAL_GL_RENDERBUFFER_BLUE_SIZE:
     270             :     case LOCAL_GL_RENDERBUFFER_ALPHA_SIZE:
     271             :     case LOCAL_GL_RENDERBUFFER_DEPTH_SIZE:
     272             :         {
     273           0 :             gl->fBindRenderbuffer(LOCAL_GL_RENDERBUFFER, mPrimaryRB);
     274           0 :             GLint i = 0;
     275           0 :             gl->fGetRenderbufferParameteriv(target.get(), pname.get(), &i);
     276           0 :             return i;
     277             :         }
     278             : 
     279             :     case LOCAL_GL_RENDERBUFFER_INTERNAL_FORMAT:
     280             :         {
     281           0 :             GLenum ret = LOCAL_GL_RGBA4;
     282           0 :             if (mFormat) {
     283           0 :                 ret = mFormat->format->sizedFormat;
     284             : 
     285           0 :                 if (!mContext->IsWebGL2() && ret == LOCAL_GL_DEPTH24_STENCIL8) {
     286           0 :                     ret = LOCAL_GL_DEPTH_STENCIL;
     287             :                 }
     288             :             }
     289           0 :             return ret;
     290             :         }
     291             :     }
     292             : 
     293           0 :     MOZ_ASSERT(false, "This function should only be called with valid `pname`.");
     294             :     return 0;
     295             : }
     296             : 
     297           0 : NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE_0(WebGLRenderbuffer)
     298             : 
     299           0 : NS_IMPL_CYCLE_COLLECTION_ROOT_NATIVE(WebGLRenderbuffer, AddRef)
     300           0 : NS_IMPL_CYCLE_COLLECTION_UNROOT_NATIVE(WebGLRenderbuffer, Release)
     301             : 
     302             : } // namespace mozilla

Generated by: LCOV version 1.13