WebGL2ContextMRTs.cpp (4452B)
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 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 "GLContext.h" 7 #include "WebGL2Context.h" 8 #include "WebGLFramebuffer.h" 9 10 namespace mozilla { 11 12 bool WebGL2Context::ValidateClearBuffer(const GLenum buffer, 13 const GLint drawBuffer, 14 const webgl::AttribBaseType funcType) { 15 GLint maxDrawBuffer; 16 switch (buffer) { 17 case LOCAL_GL_COLOR: 18 maxDrawBuffer = Limits().maxColorDrawBuffers - 1; 19 break; 20 21 case LOCAL_GL_DEPTH: 22 case LOCAL_GL_STENCIL: 23 maxDrawBuffer = 0; 24 break; 25 26 case LOCAL_GL_DEPTH_STENCIL: 27 maxDrawBuffer = 0; 28 break; 29 30 default: 31 ErrorInvalidEnumInfo("buffer", buffer); 32 return false; 33 } 34 35 if (drawBuffer < 0 || drawBuffer > maxDrawBuffer) { 36 ErrorInvalidValue( 37 "Invalid drawbuffer %d. This buffer only supports" 38 " `drawbuffer` values between 0 and %u.", 39 drawBuffer, maxDrawBuffer); 40 return false; 41 } 42 43 //// 44 45 if (!BindCurFBForDraw()) return false; 46 47 const auto& fb = mBoundDrawFramebuffer; 48 if (fb) { 49 if (!fb->ValidateClearBufferType(buffer, drawBuffer, funcType)) 50 return false; 51 } else if (buffer == LOCAL_GL_COLOR) { 52 if (drawBuffer != 0) return true; 53 54 if (mDefaultFB_DrawBuffer0 == LOCAL_GL_NONE) return true; 55 56 if (funcType != webgl::AttribBaseType::Float) { 57 ErrorInvalidOperation( 58 "For default framebuffer, COLOR is always of type" 59 " FLOAT."); 60 return false; 61 } 62 } 63 64 return true; 65 } 66 67 //// 68 69 void WebGL2Context::ClearBufferTv(GLenum buffer, GLint drawBuffer, 70 const webgl::TypedQuad& data) { 71 const FuncScope funcScope(*this, "clearBufferu?[fi]v"); 72 if (IsContextLost()) return; 73 74 switch (data.type) { 75 case webgl::AttribBaseType::Boolean: 76 MOZ_ASSERT(false); 77 return; 78 79 case webgl::AttribBaseType::Float: 80 if (buffer != LOCAL_GL_COLOR && buffer != LOCAL_GL_DEPTH) { 81 ErrorInvalidEnum("`buffer` must be COLOR or DEPTH."); 82 return; 83 } 84 break; 85 86 case webgl::AttribBaseType::Int: 87 if (buffer != LOCAL_GL_COLOR && buffer != LOCAL_GL_STENCIL) { 88 ErrorInvalidEnum("`buffer` must be COLOR or STENCIL."); 89 return; 90 } 91 break; 92 93 case webgl::AttribBaseType::Uint: 94 if (buffer != LOCAL_GL_COLOR) { 95 ErrorInvalidEnum("`buffer` must be COLOR."); 96 return; 97 } 98 break; 99 } 100 101 if (!ValidateClearBuffer(buffer, drawBuffer, data.type)) { 102 return; 103 } 104 105 if (!mBoundDrawFramebuffer && buffer == LOCAL_GL_DEPTH && mNeedsFakeNoDepth) { 106 return; 107 } 108 if (!mBoundDrawFramebuffer && buffer == LOCAL_GL_STENCIL && 109 mNeedsFakeNoStencil) { 110 return; 111 } 112 113 ScopedDrawCallWrapper wrapper(*this); 114 switch (data.type) { 115 case webgl::AttribBaseType::Boolean: 116 MOZ_ASSERT(false); 117 return; 118 119 case webgl::AttribBaseType::Float: 120 gl->fClearBufferfv(buffer, drawBuffer, 121 reinterpret_cast<const float*>(data.data.data())); 122 break; 123 124 case webgl::AttribBaseType::Int: 125 gl->fClearBufferiv(buffer, drawBuffer, 126 reinterpret_cast<const int32_t*>(data.data.data())); 127 break; 128 129 case webgl::AttribBaseType::Uint: 130 gl->fClearBufferuiv(buffer, drawBuffer, 131 reinterpret_cast<const uint32_t*>(data.data.data())); 132 break; 133 } 134 } 135 136 //// 137 138 void WebGL2Context::ClearBufferfi(GLenum buffer, GLint drawBuffer, 139 GLfloat depth, GLint stencil) { 140 const FuncScope funcScope(*this, "clearBufferfi"); 141 if (IsContextLost()) return; 142 143 if (buffer != LOCAL_GL_DEPTH_STENCIL) 144 return ErrorInvalidEnum("`buffer` must be DEPTH_STENCIL."); 145 146 const auto ignored = webgl::AttribBaseType::Float; 147 if (!ValidateClearBuffer(buffer, drawBuffer, ignored)) return; 148 149 auto driverDepth = depth; 150 auto driverStencil = stencil; 151 if (!mBoundDrawFramebuffer) { 152 if (mNeedsFakeNoDepth) { 153 driverDepth = 1.0f; 154 } else if (mNeedsFakeNoStencil) { 155 driverStencil = 0; 156 } 157 } 158 159 ScopedDrawCallWrapper wrapper(*this); 160 gl->fClearBufferfi(buffer, drawBuffer, driverDepth, driverStencil); 161 } 162 163 } // namespace mozilla