mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-27 23:02:20 +00:00
f608e1f1e0
``` // We guarantee our robustness via these requirements: // * Object.MutTiedFields() gives us a tuple, // * where the combined sizeofs all field types sums to sizeof(Object), // * (thus we know we are exhaustively listing all fields) // * where feeding each field back into ParamTraits succeeds, // * and ParamTraits is only automated for BytesAlwaysValidT<T> types. // (BytesAlwaysValidT rejects bool and enum types, and only accepts int/float // types, or array or std::arrays of such types) // (Yes, bit-field fields are rejected by MutTiedFields too) ``` BytesAlwaysValidT<T> is the same as the IsTriviallySerializable<T> that it replaces, however the emphasis is different, and should discourage tagging structs as IsTriviallySerializable, since they more clearly aren't BytesAlwaysValid. Differential Revision: https://phabricator.services.mozilla.com/D151676
165 lines
4.3 KiB
C++
165 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.data()));
|
|
break;
|
|
|
|
case webgl::AttribBaseType::Int:
|
|
gl->fClearBufferiv(buffer, drawBuffer,
|
|
reinterpret_cast<const int32_t*>(data.data.data()));
|
|
break;
|
|
|
|
case webgl::AttribBaseType::Uint:
|
|
gl->fClearBufferuiv(buffer, drawBuffer,
|
|
reinterpret_cast<const uint32_t*>(data.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
|