forked from mirrors/gecko-dev
		
	 e1d0fe64bb
			
		
	
	
		e1d0fe64bb
		
	
	
	
	
		
			
			* Context loss using RAII * Move Program reflection Client-side Depends on D54018 Differential Revision: https://phabricator.services.mozilla.com/D54019 --HG-- extra : moz-landing-system : lando
		
			
				
	
	
		
			164 lines
		
	
	
	
		
			4.3 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			164 lines
		
	
	
	
		
			4.3 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
| /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 | |
| /* This Source Code Form is subject to the terms of the Mozilla Public
 | |
|  * License, v. 2.0. If a copy of the MPL was not distributed with this
 | |
|  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 | |
| 
 | |
| #include "WebGL2Context.h"
 | |
| 
 | |
| #include "GLContext.h"
 | |
| #include "WebGLFramebuffer.h"
 | |
| 
 | |
| namespace mozilla {
 | |
| 
 | |
| bool WebGL2Context::ValidateClearBuffer(const GLenum buffer,
 | |
|                                         const GLint drawBuffer,
 | |
|                                         const webgl::AttribBaseType funcType) {
 | |
|   GLint maxDrawBuffer;
 | |
|   switch (buffer) {
 | |
|     case LOCAL_GL_COLOR:
 | |
|       maxDrawBuffer = Limits().maxColorDrawBuffers - 1;
 | |
|       break;
 | |
| 
 | |
|     case LOCAL_GL_DEPTH:
 | |
|     case LOCAL_GL_STENCIL:
 | |
|       maxDrawBuffer = 0;
 | |
|       break;
 | |
| 
 | |
|     case LOCAL_GL_DEPTH_STENCIL:
 | |
|       maxDrawBuffer = 0;
 | |
|       break;
 | |
| 
 | |
|     default:
 | |
|       ErrorInvalidEnumInfo("buffer", buffer);
 | |
|       return false;
 | |
|   }
 | |
| 
 | |
|   if (drawBuffer < 0 || drawBuffer > maxDrawBuffer) {
 | |
|     ErrorInvalidValue(
 | |
|         "Invalid drawbuffer %d. This buffer only supports"
 | |
|         " `drawbuffer` values between 0 and %u.",
 | |
|         drawBuffer, maxDrawBuffer);
 | |
|     return false;
 | |
|   }
 | |
| 
 | |
|   ////
 | |
| 
 | |
|   if (!BindCurFBForDraw()) return false;
 | |
| 
 | |
|   const auto& fb = mBoundDrawFramebuffer;
 | |
|   if (fb) {
 | |
|     if (!fb->ValidateClearBufferType(buffer, drawBuffer, funcType))
 | |
|       return false;
 | |
|   } else if (buffer == LOCAL_GL_COLOR) {
 | |
|     if (drawBuffer != 0) return true;
 | |
| 
 | |
|     if (mDefaultFB_DrawBuffer0 == LOCAL_GL_NONE) return true;
 | |
| 
 | |
|     if (funcType != webgl::AttribBaseType::Float) {
 | |
|       ErrorInvalidOperation(
 | |
|           "For default framebuffer, COLOR is always of type"
 | |
|           " FLOAT.");
 | |
|       return false;
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   return true;
 | |
| }
 | |
| 
 | |
| ////
 | |
| 
 | |
| void WebGL2Context::ClearBufferTv(GLenum buffer, GLint drawBuffer,
 | |
|                                   const webgl::TypedQuad& data) {
 | |
|   const FuncScope funcScope(*this, "clearBufferu?[fi]v");
 | |
|   if (IsContextLost()) return;
 | |
| 
 | |
|   switch (data.type) {
 | |
|     case webgl::AttribBaseType::Boolean:
 | |
|       MOZ_ASSERT(false);
 | |
|       return;
 | |
| 
 | |
|     case webgl::AttribBaseType::Float:
 | |
|       if (buffer != LOCAL_GL_COLOR && buffer != LOCAL_GL_DEPTH) {
 | |
|         ErrorInvalidEnum("`buffer` must be COLOR or DEPTH.");
 | |
|         return;
 | |
|       }
 | |
|       break;
 | |
| 
 | |
|     case webgl::AttribBaseType::Int:
 | |
|       if (buffer != LOCAL_GL_COLOR && buffer != LOCAL_GL_STENCIL) {
 | |
|         ErrorInvalidEnum("`buffer` must be COLOR or STENCIL.");
 | |
|         return;
 | |
|       }
 | |
|       break;
 | |
| 
 | |
|     case webgl::AttribBaseType::Uint:
 | |
|       if (buffer != LOCAL_GL_COLOR) {
 | |
|         ErrorInvalidEnum("`buffer` must be COLOR.");
 | |
|         return;
 | |
|       }
 | |
|       break;
 | |
|   }
 | |
| 
 | |
|   if (!ValidateClearBuffer(buffer, drawBuffer, data.type)) {
 | |
|     return;
 | |
|   }
 | |
| 
 | |
|   if (!mBoundDrawFramebuffer && buffer == LOCAL_GL_DEPTH && mNeedsFakeNoDepth) {
 | |
|     return;
 | |
|   }
 | |
|   if (!mBoundDrawFramebuffer && buffer == LOCAL_GL_STENCIL &&
 | |
|       mNeedsFakeNoStencil) {
 | |
|     return;
 | |
|   }
 | |
| 
 | |
|   ScopedDrawCallWrapper wrapper(*this);
 | |
|   switch (data.type) {
 | |
|     case webgl::AttribBaseType::Boolean:
 | |
|       MOZ_ASSERT(false);
 | |
|       return;
 | |
| 
 | |
|     case webgl::AttribBaseType::Float:
 | |
|       gl->fClearBufferfv(buffer, drawBuffer,
 | |
|                          reinterpret_cast<const float*>(data.data));
 | |
|       break;
 | |
| 
 | |
|     case webgl::AttribBaseType::Int:
 | |
|       gl->fClearBufferiv(buffer, drawBuffer,
 | |
|                          reinterpret_cast<const int32_t*>(data.data));
 | |
|       break;
 | |
| 
 | |
|     case webgl::AttribBaseType::Uint:
 | |
|       gl->fClearBufferuiv(buffer, drawBuffer,
 | |
|                           reinterpret_cast<const uint32_t*>(data.data));
 | |
|       break;
 | |
|   }
 | |
| }
 | |
| 
 | |
| ////
 | |
| 
 | |
| void WebGL2Context::ClearBufferfi(GLenum buffer, GLint drawBuffer,
 | |
|                                   GLfloat depth, GLint stencil) {
 | |
|   const FuncScope funcScope(*this, "clearBufferfi");
 | |
|   if (IsContextLost()) return;
 | |
| 
 | |
|   if (buffer != LOCAL_GL_DEPTH_STENCIL)
 | |
|     return ErrorInvalidEnum("`buffer` must be DEPTH_STENCIL.");
 | |
| 
 | |
|   const auto ignored = webgl::AttribBaseType::Float;
 | |
|   if (!ValidateClearBuffer(buffer, drawBuffer, ignored)) return;
 | |
| 
 | |
|   auto driverDepth = depth;
 | |
|   auto driverStencil = stencil;
 | |
|   if (!mBoundDrawFramebuffer) {
 | |
|     if (mNeedsFakeNoDepth) {
 | |
|       driverDepth = 1.0f;
 | |
|     } else if (mNeedsFakeNoStencil) {
 | |
|       driverStencil = 0;
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   ScopedDrawCallWrapper wrapper(*this);
 | |
|   gl->fClearBufferfi(buffer, drawBuffer, driverDepth, driverStencil);
 | |
| }
 | |
| 
 | |
| }  // namespace mozilla
 |