mirror of
https://github.com/roytam1/palemoon27.git
synced 2026-05-26 14:18:48 +00:00
cbff465051
- Bug 1167420 - Handle fallible AppendElement call in netwerk/base/Dashboard.cpp. r=valentin (a485b8990) - Bug 968520 - Add mozilla::fallible to FallibleTArray::AppendElement calls. r=froydnj (12a529a0e) - Bug 1172584 - Avoid coping FallibleTArray in SendRequestRunnable constructor. r=dragana (c3a4a4253) - Bug 948466: Rename gfxPangoFonts to gfxFontconfigFonts. r=nical (43eed1f5f) - Bug 968520 - Add mozilla::fallible to more FallibleTArray calls. r=froydnj (339968a1d) - Bug 1166544 - Assume successful InsertElementAt calls in DOMSVG*List::MaybeInsertNullInAnimValListAt. r=dholbert (cf687dad7) - Bug 968520 - Add mozilla::fallible to FallibleTArray::InsertElementAt calls. r=froydnj (cc5c68ff2) - Bug 968520 - Add mozilla::fallible to more FallibleTArray::InsertElementsAt calls. r=froydnj (66df1d034) - Bug 1165735 - Make ThreadSharedFloatArrayBufferList::mContents infallible. r=roc (eda2839db) - Bug 1166544 - Use ReplaceElementAt instead of Clear and InsertElementAt in SVGMotionSMILType::Add. r=dholbert (474887a8c) - Bug 1167418 - Check AppendElement call in MediaQueryList. r=heycam (b6ed6d153) - Bug 1167418 - Use nsTArray instead of FallibleTArray in MediaQueryList. r=heycam (c9e3816d0) - Bug 1167418 - Follow-up: Fix bustage (5015e91ce) - Bug 1174220 - Part 1: Remove capacity constructor of MediaLargeByteBuffer. r=jya (66819d3e4) - Bug 1179282 - Use nsTArray::Assign instead of the assignment operator in dom/svg/. r=dholbert (cb3d43c19) - Bug 968520 - Add nsTArray::Assign. r=froydnj (e5eccf354) - Bug 1182277, don't leak when using nsAutoTArray inside nsTArray, r=nfroyd (bba32394c) - Bug 1143575. Avoid including Android's GraphicBuffer.h from LayersTypes.h. r=nical (99e4e2816) - Bug 1143575. Avoid use of COMPARE macro which can clash with Android headers. r=bent (99cfc74c4) - Bug 1143575. Add RefBase #include to stagefright stubs. r=cpearce (f9e327600) - Bug 1143575. test_HaveMetadataUnbufferedSeek should not wait for canplay since preload='metadata' elements may not fire canplay. r=cpearce (f1b0eee27) - Bug 1143575. Make GL context current before cleaning up programs. r=nical (d7b05b2bd) - partial Bug 1143575. Android's screenshotting code should invalidate the LayrManagerComposite to ensure composition will actually happen. r=nical (58fb296ab) - Bug 1143575. Remove unused Image::IsSentToCompositor tracking. r=nical (808d0b3f0) - Bug 1143575. Remove unused CompositionNotifySink. r=nical (98a332305) - Bug 1143575. Remove unused VideoFrameContainer::Reset. r=nical (e292bc722) - Bug 1143575. Rename mAsyncTransactionTrackeres to mAsyncTransactionTrackers. r=nical (df71ebf4f) - Bug 1143575. Remove unused ImageContainer::ResetPaintCount. r=nical (a92c5bf6e) - Bug 1143575. Remove unused VideoFrameContainer::ClearCurrentFrame aResetSize parameter. r=nical (5d3c9b83a) - Bug 1143575. Remove unused ReturnReleaseFence. r=nical (9d6ea92b5) - Bug 1143575. LayerManagerComposite can't get END_NO_COMPOSITE. r=mattwoodrow (0c5c364b5) - Bug 1143575. Remove unused AttachAsyncCompositable overload. r=nical (5fd3d4f6d) - Bug 1143575. Rename ImageBridgeChild's AutoRemoteTextures to AutoRemoveTexturesFromImageBridge to avoid clashes with later work. r=nical (34d67fcc0) - Bug 1143575. Fix some code formatting. r=nical (1d7f30f60) - Bug 1143575. Move mLayer from ImageClientBridge up into its superclass ImageClient. r=nical (40c902a36) - Bug 1127336 - Label HW-decoded frames with correct origin. - r=vlad (fd1580bcd) - Bug 1167504 - Part 1: Remove BindableName - Framebuffer. r=jgilbert (b3133eee6) - Bug 1167504 - Part 2: Remove BindableName - Renderbuffer. r=jgilbert (155a7e796) - Bug 1167504 - Part 3: Remove BindableName - Sampler. r=jgilbert (8c5c68960) - Bug 1167504 - Part 4: Remove BindableName - Texture. r=jgilbert (28077db04) - Bug 1167504 - Part 5: Remove BindableName - Transform Feedback. r=jgilbert (4fd839598) - Bug 1170454: Fix up instance type for VAOs. r=smaug,r=jgilbert (cc62d993a) - Bug 1167504 - Part 6: Remove BindableName - Vertex Array. r=jgilbert (1d54d5bc1) - Bug 1048724 - Implement GetBufferSubData. r=jgilbert, r=smaug (06570aa84) - Bug 1167504 - Part 7: Remove BindableName - Buffer. r=jgilbert (b2ddf3fc6)
525 lines
16 KiB
C++
525 lines
16 KiB
C++
/* -*- 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 "WebGLContextUtils.h"
|
|
|
|
using namespace mozilla;
|
|
using namespace mozilla::dom;
|
|
|
|
// Returns one of FLOAT, INT, UNSIGNED_INT.
|
|
// Fixed-points (normalized ints) are considered FLOAT.
|
|
static GLenum
|
|
ValueTypeForFormat(GLenum internalFormat)
|
|
{
|
|
switch (internalFormat) {
|
|
// Fixed-point
|
|
case LOCAL_GL_R8:
|
|
case LOCAL_GL_RG8:
|
|
case LOCAL_GL_RGB565:
|
|
case LOCAL_GL_RGB8:
|
|
case LOCAL_GL_RGBA4:
|
|
case LOCAL_GL_RGB5_A1:
|
|
case LOCAL_GL_RGBA8:
|
|
case LOCAL_GL_RGB10_A2:
|
|
case LOCAL_GL_ALPHA8:
|
|
case LOCAL_GL_LUMINANCE8:
|
|
case LOCAL_GL_LUMINANCE8_ALPHA8:
|
|
case LOCAL_GL_SRGB8:
|
|
case LOCAL_GL_SRGB8_ALPHA8:
|
|
case LOCAL_GL_R8_SNORM:
|
|
case LOCAL_GL_RG8_SNORM:
|
|
case LOCAL_GL_RGB8_SNORM:
|
|
case LOCAL_GL_RGBA8_SNORM:
|
|
|
|
// Floating-point
|
|
case LOCAL_GL_R16F:
|
|
case LOCAL_GL_RG16F:
|
|
case LOCAL_GL_RGB16F:
|
|
case LOCAL_GL_RGBA16F:
|
|
case LOCAL_GL_ALPHA16F_EXT:
|
|
case LOCAL_GL_LUMINANCE16F_EXT:
|
|
case LOCAL_GL_LUMINANCE_ALPHA16F_EXT:
|
|
|
|
case LOCAL_GL_R32F:
|
|
case LOCAL_GL_RG32F:
|
|
case LOCAL_GL_RGB32F:
|
|
case LOCAL_GL_RGBA32F:
|
|
case LOCAL_GL_ALPHA32F_EXT:
|
|
case LOCAL_GL_LUMINANCE32F_EXT:
|
|
case LOCAL_GL_LUMINANCE_ALPHA32F_EXT:
|
|
|
|
case LOCAL_GL_R11F_G11F_B10F:
|
|
case LOCAL_GL_RGB9_E5:
|
|
return LOCAL_GL_FLOAT;
|
|
|
|
// Int
|
|
case LOCAL_GL_R8I:
|
|
case LOCAL_GL_RG8I:
|
|
case LOCAL_GL_RGB8I:
|
|
case LOCAL_GL_RGBA8I:
|
|
|
|
case LOCAL_GL_R16I:
|
|
case LOCAL_GL_RG16I:
|
|
case LOCAL_GL_RGB16I:
|
|
case LOCAL_GL_RGBA16I:
|
|
|
|
case LOCAL_GL_R32I:
|
|
case LOCAL_GL_RG32I:
|
|
case LOCAL_GL_RGB32I:
|
|
case LOCAL_GL_RGBA32I:
|
|
return LOCAL_GL_INT;
|
|
|
|
// Unsigned int
|
|
case LOCAL_GL_R8UI:
|
|
case LOCAL_GL_RG8UI:
|
|
case LOCAL_GL_RGB8UI:
|
|
case LOCAL_GL_RGBA8UI:
|
|
|
|
case LOCAL_GL_R16UI:
|
|
case LOCAL_GL_RG16UI:
|
|
case LOCAL_GL_RGB16UI:
|
|
case LOCAL_GL_RGBA16UI:
|
|
|
|
case LOCAL_GL_R32UI:
|
|
case LOCAL_GL_RG32UI:
|
|
case LOCAL_GL_RGB32UI:
|
|
case LOCAL_GL_RGBA32UI:
|
|
|
|
case LOCAL_GL_RGB10_A2UI:
|
|
return LOCAL_GL_UNSIGNED_INT;
|
|
|
|
default:
|
|
MOZ_CRASH("Bad `internalFormat`.");
|
|
}
|
|
}
|
|
|
|
// -------------------------------------------------------------------------
|
|
// Framebuffer objects
|
|
|
|
static bool
|
|
GetFBInfoForBlit(const WebGLFramebuffer* fb, WebGLContext* webgl,
|
|
const char* const fbInfo, GLsizei* const out_samples,
|
|
GLenum* const out_colorFormat, GLenum* const out_depthFormat,
|
|
GLenum* const out_stencilFormat)
|
|
{
|
|
auto status = fb->PrecheckFramebufferStatus();
|
|
if (status != LOCAL_GL_FRAMEBUFFER_COMPLETE) {
|
|
webgl->ErrorInvalidOperation("blitFramebuffer: %s is not"
|
|
" framebuffer-complete.", fbInfo);
|
|
return false;
|
|
}
|
|
|
|
*out_samples = 1; // TODO
|
|
|
|
if (fb->ColorAttachment(0).IsDefined()) {
|
|
const auto& attachement = fb->ColorAttachment(0);
|
|
*out_colorFormat = attachement.EffectiveInternalFormat().get();
|
|
} else {
|
|
*out_colorFormat = 0;
|
|
}
|
|
|
|
if (fb->DepthStencilAttachment().IsDefined()) {
|
|
const auto& attachement = fb->DepthStencilAttachment();
|
|
*out_depthFormat = attachement.EffectiveInternalFormat().get();
|
|
*out_stencilFormat = *out_depthFormat;
|
|
} else {
|
|
if (fb->DepthAttachment().IsDefined()) {
|
|
const auto& attachement = fb->DepthAttachment();
|
|
*out_depthFormat = attachement.EffectiveInternalFormat().get();
|
|
} else {
|
|
*out_depthFormat = 0;
|
|
}
|
|
|
|
if (fb->StencilAttachment().IsDefined()) {
|
|
const auto& attachement = fb->StencilAttachment();
|
|
*out_stencilFormat = attachement.EffectiveInternalFormat().get();
|
|
} else {
|
|
*out_stencilFormat = 0;
|
|
}
|
|
}
|
|
return true;
|
|
}
|
|
|
|
void
|
|
WebGL2Context::BlitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
|
|
GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
|
|
GLbitfield mask, GLenum filter)
|
|
{
|
|
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 GLbitfield depthAndStencilBits = LOCAL_GL_DEPTH_BUFFER_BIT |
|
|
LOCAL_GL_STENCIL_BUFFER_BIT;
|
|
if (mask & depthAndStencilBits &&
|
|
filter != LOCAL_GL_NEAREST)
|
|
{
|
|
ErrorInvalidOperation("blitFramebuffer: DEPTH_BUFFER_BIT and"
|
|
" STENCIL_BUFFER_BIT can only be used with"
|
|
" NEAREST filtering.");
|
|
return;
|
|
}
|
|
|
|
if (mBoundReadFramebuffer == mBoundDrawFramebuffer) {
|
|
// TODO: It's actually more complicated than this. We need to check that
|
|
// the underlying buffers are not the same, not the framebuffers
|
|
// themselves.
|
|
ErrorInvalidOperation("blitFramebuffer: Source and destination must"
|
|
" differ.");
|
|
return;
|
|
}
|
|
|
|
GLsizei srcSamples;
|
|
GLenum srcColorFormat;
|
|
GLenum srcDepthFormat;
|
|
GLenum srcStencilFormat;
|
|
|
|
if (mBoundReadFramebuffer) {
|
|
if (!GetFBInfoForBlit(mBoundReadFramebuffer, this, "READ_FRAMEBUFFER",
|
|
&srcSamples, &srcColorFormat, &srcDepthFormat,
|
|
&srcStencilFormat))
|
|
{
|
|
return;
|
|
}
|
|
} else {
|
|
srcSamples = 1; // Always 1.
|
|
|
|
// TODO: Don't hardcode these.
|
|
srcColorFormat = mOptions.alpha ? LOCAL_GL_RGBA8 : LOCAL_GL_RGB8;
|
|
|
|
if (mOptions.depth && mOptions.stencil) {
|
|
srcDepthFormat = LOCAL_GL_DEPTH24_STENCIL8;
|
|
srcStencilFormat = srcDepthFormat;
|
|
} else {
|
|
if (mOptions.depth) {
|
|
srcDepthFormat = LOCAL_GL_DEPTH_COMPONENT16;
|
|
}
|
|
if (mOptions.stencil) {
|
|
srcStencilFormat = LOCAL_GL_STENCIL_INDEX8;
|
|
}
|
|
}
|
|
}
|
|
|
|
GLsizei dstSamples;
|
|
GLenum dstColorFormat;
|
|
GLenum dstDepthFormat;
|
|
GLenum dstStencilFormat;
|
|
|
|
if (mBoundDrawFramebuffer) {
|
|
if (!GetFBInfoForBlit(mBoundDrawFramebuffer, this, "DRAW_FRAMEBUFFER",
|
|
&dstSamples, &dstColorFormat, &dstDepthFormat,
|
|
&dstStencilFormat))
|
|
{
|
|
return;
|
|
}
|
|
} else {
|
|
dstSamples = gl->Screen()->Samples();
|
|
|
|
// TODO: Don't hardcode these.
|
|
dstColorFormat = mOptions.alpha ? LOCAL_GL_RGBA8 : LOCAL_GL_RGB8;
|
|
|
|
if (mOptions.depth && mOptions.stencil) {
|
|
dstDepthFormat = LOCAL_GL_DEPTH24_STENCIL8;
|
|
dstStencilFormat = dstDepthFormat;
|
|
} else {
|
|
if (mOptions.depth) {
|
|
dstDepthFormat = LOCAL_GL_DEPTH_COMPONENT16;
|
|
}
|
|
if (mOptions.stencil) {
|
|
dstStencilFormat = LOCAL_GL_STENCIL_INDEX8;
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
if (mask & LOCAL_GL_COLOR_BUFFER_BIT) {
|
|
const GLenum srcColorType = srcColorFormat ? ValueTypeForFormat(srcColorFormat)
|
|
: 0;
|
|
const GLenum dstColorType = dstColorFormat ? ValueTypeForFormat(dstColorFormat)
|
|
: 0;
|
|
if (dstColorType != srcColorType) {
|
|
ErrorInvalidOperation("blitFramebuffer: Color buffer value type"
|
|
" mismatch.");
|
|
return;
|
|
}
|
|
|
|
const bool srcIsInt = srcColorType == LOCAL_GL_INT ||
|
|
srcColorType == LOCAL_GL_UNSIGNED_INT;
|
|
if (srcIsInt && filter != LOCAL_GL_NEAREST) {
|
|
ErrorInvalidOperation("blitFramebuffer: Integer read buffers can only"
|
|
" be filtered with NEAREST.");
|
|
return;
|
|
}
|
|
}
|
|
|
|
/* GLES 3.0.4, p199:
|
|
* Calling BlitFramebuffer will result in an INVALID_OPERATION error if
|
|
* mask includes DEPTH_BUFFER_BIT or STENCIL_BUFFER_BIT, and the source
|
|
* and destination depth and stencil buffer formats do not match.
|
|
*
|
|
* jgilbert: The wording is such that if only DEPTH_BUFFER_BIT is specified,
|
|
* the stencil formats must match. This seems wrong. It could be a spec bug,
|
|
* or I could be missing an interaction in one of the earlier paragraphs.
|
|
*/
|
|
if (mask & LOCAL_GL_DEPTH_BUFFER_BIT &&
|
|
dstDepthFormat != srcDepthFormat)
|
|
{
|
|
ErrorInvalidOperation("blitFramebuffer: Depth buffer formats must match"
|
|
" if selected.");
|
|
return;
|
|
}
|
|
|
|
if (mask & LOCAL_GL_STENCIL_BUFFER_BIT &&
|
|
dstStencilFormat != srcStencilFormat)
|
|
{
|
|
ErrorInvalidOperation("blitFramebuffer: Stencil buffer formats must"
|
|
" match if selected.");
|
|
return;
|
|
}
|
|
|
|
if (dstSamples != 1) {
|
|
ErrorInvalidOperation("blitFramebuffer: DRAW_FRAMEBUFFER may not have"
|
|
" multiple samples.");
|
|
return;
|
|
}
|
|
|
|
if (srcSamples != 1) {
|
|
if (mask & LOCAL_GL_COLOR_BUFFER_BIT &&
|
|
dstColorFormat != srcColorFormat)
|
|
{
|
|
ErrorInvalidOperation("blitFramebuffer: Color buffer formats must"
|
|
" match if selected, when reading from a"
|
|
" multisampled source.");
|
|
return;
|
|
}
|
|
|
|
if (dstX0 != srcX0 ||
|
|
dstX1 != srcX1 ||
|
|
dstY0 != srcY0 ||
|
|
dstY1 != srcY1)
|
|
{
|
|
ErrorInvalidOperation("blitFramebuffer: If the source is"
|
|
" multisampled, then the source and dest"
|
|
" regions must match exactly.");
|
|
return;
|
|
}
|
|
}
|
|
|
|
MakeContextCurrent();
|
|
gl->fBlitFramebuffer(srcX0, srcY0, srcX1, srcY1,
|
|
dstX0, dstY0, dstX1, dstY1,
|
|
mask, filter);
|
|
}
|
|
|
|
void
|
|
WebGL2Context::FramebufferTextureLayer(GLenum target, GLenum attachment, GLuint texture, GLint level, GLint layer)
|
|
{
|
|
MOZ_CRASH("Not Implemented.");
|
|
}
|
|
|
|
void
|
|
WebGL2Context::GetInternalformatParameter(JSContext*, GLenum target, GLenum internalformat, GLenum pname, JS::MutableHandleValue retval)
|
|
{
|
|
MOZ_CRASH("Not Implemented.");
|
|
}
|
|
|
|
// Map attachments intended for the default buffer, to attachments for a non-
|
|
// default buffer.
|
|
static bool
|
|
TranslateDefaultAttachments(const dom::Sequence<GLenum>& in, dom::Sequence<GLenum>* out)
|
|
{
|
|
for (size_t i = 0; i < in.Length(); i++) {
|
|
switch (in[i]) {
|
|
case LOCAL_GL_COLOR:
|
|
if (!out->AppendElement(LOCAL_GL_COLOR_ATTACHMENT0, fallible)) {
|
|
return false;
|
|
}
|
|
break;
|
|
|
|
case LOCAL_GL_DEPTH:
|
|
if (!out->AppendElement(LOCAL_GL_DEPTH_ATTACHMENT, fallible)) {
|
|
return false;
|
|
}
|
|
break;
|
|
|
|
case LOCAL_GL_STENCIL:
|
|
if (!out->AppendElement(LOCAL_GL_STENCIL_ATTACHMENT, fallible)) {
|
|
return false;
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
void
|
|
WebGL2Context::InvalidateFramebuffer(GLenum target,
|
|
const dom::Sequence<GLenum>& attachments,
|
|
ErrorResult& aRv)
|
|
{
|
|
if (IsContextLost())
|
|
return;
|
|
|
|
MakeContextCurrent();
|
|
|
|
if (!ValidateFramebufferTarget(target, "framebufferRenderbuffer"))
|
|
return;
|
|
|
|
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("Bad target.");
|
|
}
|
|
|
|
for (size_t i = 0; i < attachments.Length(); i++) {
|
|
if (!ValidateFramebufferAttachment(fb, attachments[i],
|
|
"invalidateFramebuffer"))
|
|
{
|
|
return;
|
|
}
|
|
}
|
|
|
|
if (!fb && !isDefaultFB) {
|
|
dom::Sequence<GLenum> tmpAttachments;
|
|
if (!TranslateDefaultAttachments(attachments, &tmpAttachments)) {
|
|
aRv.Throw(NS_ERROR_OUT_OF_MEMORY);
|
|
return;
|
|
}
|
|
|
|
gl->fInvalidateFramebuffer(target, tmpAttachments.Length(), tmpAttachments.Elements());
|
|
} else {
|
|
gl->fInvalidateFramebuffer(target, attachments.Length(), attachments.Elements());
|
|
}
|
|
}
|
|
|
|
void
|
|
WebGL2Context::InvalidateSubFramebuffer(GLenum target, const dom::Sequence<GLenum>& attachments,
|
|
GLint x, GLint y, GLsizei width, GLsizei height,
|
|
ErrorResult& aRv)
|
|
{
|
|
if (IsContextLost())
|
|
return;
|
|
|
|
MakeContextCurrent();
|
|
|
|
if (!ValidateFramebufferTarget(target, "framebufferRenderbuffer"))
|
|
return;
|
|
|
|
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("Bad target.");
|
|
}
|
|
|
|
for (size_t i = 0; i < attachments.Length(); i++) {
|
|
if (!ValidateFramebufferAttachment(fb, attachments[i],
|
|
"invalidateSubFramebuffer"))
|
|
{
|
|
return;
|
|
}
|
|
}
|
|
|
|
if (!fb && !isDefaultFB) {
|
|
dom::Sequence<GLenum> tmpAttachments;
|
|
if (!TranslateDefaultAttachments(attachments, &tmpAttachments)) {
|
|
aRv.Throw(NS_ERROR_OUT_OF_MEMORY);
|
|
return;
|
|
}
|
|
|
|
gl->fInvalidateSubFramebuffer(target, tmpAttachments.Length(), tmpAttachments.Elements(),
|
|
x, y, width, height);
|
|
} else {
|
|
gl->fInvalidateSubFramebuffer(target, attachments.Length(), attachments.Elements(),
|
|
x, y, width, height);
|
|
}
|
|
}
|
|
|
|
void
|
|
WebGL2Context::ReadBuffer(GLenum mode)
|
|
{
|
|
if (IsContextLost())
|
|
return;
|
|
|
|
MakeContextCurrent();
|
|
|
|
if (mBoundReadFramebuffer) {
|
|
bool isColorAttachment = (mode >= LOCAL_GL_COLOR_ATTACHMENT0 &&
|
|
mode <= LastColorAttachment());
|
|
if (mode != LOCAL_GL_NONE &&
|
|
!isColorAttachment)
|
|
{
|
|
ErrorInvalidEnumInfo("readBuffer: If READ_FRAMEBUFFER is non-null,"
|
|
" `mode` must be COLOR_ATTACHMENTN or NONE."
|
|
" Was:", mode);
|
|
return;
|
|
}
|
|
|
|
gl->fReadBuffer(mode);
|
|
return;
|
|
}
|
|
|
|
// Operating on the default framebuffer.
|
|
|
|
if (mode != LOCAL_GL_NONE &&
|
|
mode != LOCAL_GL_BACK)
|
|
{
|
|
ErrorInvalidEnumInfo("readBuffer: If READ_FRAMEBUFFER is null, `mode`"
|
|
" must be BACK or NONE. Was:", mode);
|
|
return;
|
|
}
|
|
|
|
gl->Screen()->SetReadBuffer(mode);
|
|
}
|
|
|
|
void
|
|
WebGL2Context::RenderbufferStorageMultisample(GLenum target, GLsizei samples,
|
|
GLenum internalFormat,
|
|
GLsizei width, GLsizei height)
|
|
{
|
|
RenderbufferStorage_base("renderbufferStorageMultisample", target, samples,
|
|
internalFormat, width, height);
|
|
}
|