mirror of
https://repo.dactyloidae.xyz/Dactyloidae/UXP.git
synced 2026-09-05 15:28:39 +09:00
import FIREFOX_52_6_0esr_RELEASE from mozilla-esr52 hg repo
This commit is contained in:
commit
dcd9973243
150858 changed files with 23884658 additions and 0 deletions
339
dom/canvas/WebGL2ContextFramebuffers.cpp
Normal file
339
dom/canvas/WebGL2ContextFramebuffers.cpp
Normal file
|
|
@ -0,0 +1,339 @@
|
|||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||
/* 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 "GLScreenBuffer.h"
|
||||
#include "WebGLContextUtils.h"
|
||||
#include "WebGLFormats.h"
|
||||
#include "WebGLFramebuffer.h"
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
void
|
||||
WebGL2Context::BlitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
|
||||
GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
|
||||
GLbitfield mask, GLenum filter)
|
||||
{
|
||||
if (IsContextLost())
|
||||
return;
|
||||
|
||||
const GLbitfield validBits = LOCAL_GL_COLOR_BUFFER_BIT |
|
||||
LOCAL_GL_DEPTH_BUFFER_BIT |
|
||||
LOCAL_GL_STENCIL_BUFFER_BIT;
|
||||
if ((mask | validBits) != validBits) {
|
||||
ErrorInvalidValue("blitFramebuffer: Invalid bit set in mask.");
|
||||
return;
|
||||
}
|
||||
|
||||
switch (filter) {
|
||||
case LOCAL_GL_NEAREST:
|
||||
case LOCAL_GL_LINEAR:
|
||||
break;
|
||||
default:
|
||||
ErrorInvalidEnumInfo("blitFramebuffer: Bad `filter`:", filter);
|
||||
return;
|
||||
}
|
||||
|
||||
////
|
||||
|
||||
const auto& readFB = mBoundReadFramebuffer;
|
||||
if (readFB &&
|
||||
!readFB->ValidateAndInitAttachments("blitFramebuffer's READ_FRAMEBUFFER"))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
const auto& drawFB = mBoundDrawFramebuffer;
|
||||
if (drawFB &&
|
||||
!drawFB->ValidateAndInitAttachments("blitFramebuffer's DRAW_FRAMEBUFFER"))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
////
|
||||
|
||||
if (!mBoundReadFramebuffer) {
|
||||
ClearBackbufferIfNeeded();
|
||||
}
|
||||
|
||||
WebGLFramebuffer::BlitFramebuffer(this,
|
||||
readFB, srcX0, srcY0, srcX1, srcY1,
|
||||
drawFB, dstX0, dstY0, dstX1, dstY1,
|
||||
mask, filter);
|
||||
}
|
||||
|
||||
void
|
||||
WebGL2Context::FramebufferTextureLayer(GLenum target, GLenum attachment,
|
||||
WebGLTexture* texture, GLint level, GLint layer)
|
||||
{
|
||||
const char funcName[] = "framebufferTextureLayer";
|
||||
if (IsContextLost())
|
||||
return;
|
||||
|
||||
if (!ValidateFramebufferTarget(target, funcName))
|
||||
return;
|
||||
|
||||
WebGLFramebuffer* fb;
|
||||
switch (target) {
|
||||
case LOCAL_GL_FRAMEBUFFER:
|
||||
case LOCAL_GL_DRAW_FRAMEBUFFER:
|
||||
fb = mBoundDrawFramebuffer;
|
||||
break;
|
||||
|
||||
case LOCAL_GL_READ_FRAMEBUFFER:
|
||||
fb = mBoundReadFramebuffer;
|
||||
break;
|
||||
|
||||
default:
|
||||
MOZ_CRASH("GFX: Bad target.");
|
||||
}
|
||||
|
||||
if (!fb)
|
||||
return ErrorInvalidOperation("%s: Cannot modify framebuffer 0.", funcName);
|
||||
|
||||
fb->FramebufferTextureLayer(funcName, attachment, texture, level, layer);
|
||||
}
|
||||
|
||||
JS::Value
|
||||
WebGL2Context::GetFramebufferAttachmentParameter(JSContext* cx,
|
||||
GLenum target,
|
||||
GLenum attachment,
|
||||
GLenum pname,
|
||||
ErrorResult& out_error)
|
||||
{
|
||||
return WebGLContext::GetFramebufferAttachmentParameter(cx, target, attachment, pname,
|
||||
out_error);
|
||||
}
|
||||
|
||||
////
|
||||
|
||||
static bool
|
||||
ValidateBackbufferAttachmentEnum(WebGLContext* webgl, const char* funcName,
|
||||
GLenum attachment)
|
||||
{
|
||||
switch (attachment) {
|
||||
case LOCAL_GL_COLOR:
|
||||
case LOCAL_GL_DEPTH:
|
||||
case LOCAL_GL_STENCIL:
|
||||
return true;
|
||||
|
||||
default:
|
||||
webgl->ErrorInvalidEnum("%s: attachment: invalid enum value 0x%x.",
|
||||
funcName, attachment);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
static bool
|
||||
ValidateFramebufferAttachmentEnum(WebGLContext* webgl, const char* funcName,
|
||||
GLenum attachment)
|
||||
{
|
||||
switch (attachment) {
|
||||
case LOCAL_GL_DEPTH_ATTACHMENT:
|
||||
case LOCAL_GL_STENCIL_ATTACHMENT:
|
||||
case LOCAL_GL_DEPTH_STENCIL_ATTACHMENT:
|
||||
return true;
|
||||
}
|
||||
|
||||
if (attachment < LOCAL_GL_COLOR_ATTACHMENT0) {
|
||||
webgl->ErrorInvalidEnum("%s: attachment: invalid enum value 0x%x.",
|
||||
funcName, attachment);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (attachment > webgl->LastColorAttachmentEnum()) {
|
||||
// That these errors have different types is ridiculous.
|
||||
webgl->ErrorInvalidOperation("%s: Too-large LOCAL_GL_COLOR_ATTACHMENTn.",
|
||||
funcName);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
WebGLContext::ValidateInvalidateFramebuffer(const char* funcName, GLenum target,
|
||||
const dom::Sequence<GLenum>& attachments,
|
||||
ErrorResult* const out_rv,
|
||||
std::vector<GLenum>* const scopedVector,
|
||||
GLsizei* const out_glNumAttachments,
|
||||
const GLenum** const out_glAttachments)
|
||||
{
|
||||
if (IsContextLost())
|
||||
return false;
|
||||
|
||||
gl->MakeCurrent();
|
||||
|
||||
if (!ValidateFramebufferTarget(target, funcName))
|
||||
return false;
|
||||
|
||||
const WebGLFramebuffer* fb;
|
||||
bool isDefaultFB;
|
||||
switch (target) {
|
||||
case LOCAL_GL_FRAMEBUFFER:
|
||||
case LOCAL_GL_DRAW_FRAMEBUFFER:
|
||||
fb = mBoundDrawFramebuffer;
|
||||
isDefaultFB = gl->Screen()->IsDrawFramebufferDefault();
|
||||
break;
|
||||
|
||||
case LOCAL_GL_READ_FRAMEBUFFER:
|
||||
fb = mBoundReadFramebuffer;
|
||||
isDefaultFB = gl->Screen()->IsReadFramebufferDefault();
|
||||
break;
|
||||
|
||||
default:
|
||||
MOZ_CRASH("GFX: Bad target.");
|
||||
}
|
||||
|
||||
*out_glNumAttachments = attachments.Length();
|
||||
*out_glAttachments = attachments.Elements();
|
||||
|
||||
if (fb) {
|
||||
for (const auto& attachment : attachments) {
|
||||
if (!ValidateFramebufferAttachmentEnum(this, funcName, attachment))
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
for (const auto& attachment : attachments) {
|
||||
if (!ValidateBackbufferAttachmentEnum(this, funcName, attachment))
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!isDefaultFB) {
|
||||
MOZ_ASSERT(scopedVector->empty());
|
||||
scopedVector->reserve(attachments.Length());
|
||||
for (const auto& attachment : attachments) {
|
||||
switch (attachment) {
|
||||
case LOCAL_GL_COLOR:
|
||||
scopedVector->push_back(LOCAL_GL_COLOR_ATTACHMENT0);
|
||||
break;
|
||||
|
||||
case LOCAL_GL_DEPTH:
|
||||
scopedVector->push_back(LOCAL_GL_DEPTH_ATTACHMENT);
|
||||
break;
|
||||
|
||||
case LOCAL_GL_STENCIL:
|
||||
scopedVector->push_back(LOCAL_GL_STENCIL_ATTACHMENT);
|
||||
break;
|
||||
|
||||
default:
|
||||
MOZ_CRASH();
|
||||
}
|
||||
}
|
||||
*out_glNumAttachments = scopedVector->size();
|
||||
*out_glAttachments = scopedVector->data();
|
||||
}
|
||||
}
|
||||
|
||||
////
|
||||
|
||||
if (!fb) {
|
||||
ClearBackbufferIfNeeded();
|
||||
|
||||
// Don't do more validation after these.
|
||||
Invalidate();
|
||||
mShouldPresent = true;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void
|
||||
WebGL2Context::InvalidateFramebuffer(GLenum target,
|
||||
const dom::Sequence<GLenum>& attachments,
|
||||
ErrorResult& rv)
|
||||
{
|
||||
const char funcName[] = "invalidateSubFramebuffer";
|
||||
|
||||
std::vector<GLenum> scopedVector;
|
||||
GLsizei glNumAttachments;
|
||||
const GLenum* glAttachments;
|
||||
if (!ValidateInvalidateFramebuffer(funcName, target, attachments, &rv, &scopedVector,
|
||||
&glNumAttachments, &glAttachments))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
////
|
||||
|
||||
// Some drivers (like OSX 10.9 GL) just don't support invalidate_framebuffer.
|
||||
const bool useFBInvalidation = (mAllowFBInvalidation &&
|
||||
gl->IsSupported(gl::GLFeature::invalidate_framebuffer));
|
||||
if (useFBInvalidation) {
|
||||
gl->fInvalidateFramebuffer(target, glNumAttachments, glAttachments);
|
||||
return;
|
||||
}
|
||||
|
||||
// Use clear instead?
|
||||
// No-op for now.
|
||||
}
|
||||
|
||||
void
|
||||
WebGL2Context::InvalidateSubFramebuffer(GLenum target, const dom::Sequence<GLenum>& attachments,
|
||||
GLint x, GLint y, GLsizei width, GLsizei height,
|
||||
ErrorResult& rv)
|
||||
{
|
||||
const char funcName[] = "invalidateSubFramebuffer";
|
||||
|
||||
if (!ValidateNonNegative(funcName, "width", width) ||
|
||||
!ValidateNonNegative(funcName, "height", height))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
std::vector<GLenum> scopedVector;
|
||||
GLsizei glNumAttachments;
|
||||
const GLenum* glAttachments;
|
||||
if (!ValidateInvalidateFramebuffer(funcName, target, attachments, &rv, &scopedVector,
|
||||
&glNumAttachments, &glAttachments))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
////
|
||||
|
||||
// Some drivers (like OSX 10.9 GL) just don't support invalidate_framebuffer.
|
||||
const bool useFBInvalidation = (mAllowFBInvalidation &&
|
||||
gl->IsSupported(gl::GLFeature::invalidate_framebuffer));
|
||||
if (useFBInvalidation) {
|
||||
gl->fInvalidateSubFramebuffer(target, glNumAttachments, glAttachments, x, y,
|
||||
width, height);
|
||||
return;
|
||||
}
|
||||
|
||||
// Use clear instead?
|
||||
// No-op for now.
|
||||
}
|
||||
|
||||
void
|
||||
WebGL2Context::ReadBuffer(GLenum mode)
|
||||
{
|
||||
const char funcName[] = "readBuffer";
|
||||
if (IsContextLost())
|
||||
return;
|
||||
|
||||
if (mBoundReadFramebuffer) {
|
||||
mBoundReadFramebuffer->ReadBuffer(funcName, mode);
|
||||
return;
|
||||
}
|
||||
|
||||
// Operating on the default framebuffer.
|
||||
if (mode != LOCAL_GL_NONE &&
|
||||
mode != LOCAL_GL_BACK)
|
||||
{
|
||||
nsCString enumName;
|
||||
EnumName(mode, &enumName);
|
||||
ErrorInvalidOperation("%s: If READ_FRAMEBUFFER is null, `mode` must be BACK or"
|
||||
" NONE. Was %s.",
|
||||
funcName, enumName.BeginReading());
|
||||
return;
|
||||
}
|
||||
|
||||
gl->Screen()->SetReadBuffer(mode);
|
||||
}
|
||||
|
||||
} // namespace mozilla
|
||||
Loading…
Add table
Add a link
Reference in a new issue