Bug 1193070 - Implement GetFramebufferAttachmentParameter. r=jgilbert

This commit is contained in:
Dan Glastonbury 2015-08-06 16:31:00 +10:00
parent 0900e216b1
commit 3cfffa46c5
7 changed files with 605 additions and 5 deletions

View File

@ -71,6 +71,11 @@ public:
GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
GLbitfield mask, GLenum filter);
void FramebufferTextureLayer(GLenum target, GLenum attachment, WebGLTexture* texture, GLint level, GLint layer);
virtual JS::Value GetFramebufferAttachmentParameter(JSContext* cx, GLenum target,
GLenum attachment, GLenum pname,
ErrorResult& rv) override;
void InvalidateFramebuffer(GLenum target, const dom::Sequence<GLenum>& attachments,
ErrorResult& rv);
void InvalidateSubFramebuffer (GLenum target, const dom::Sequence<GLenum>& attachments, GLint x, GLint y,

View File

@ -8,10 +8,17 @@
#include "GLContext.h"
#include "GLScreenBuffer.h"
#include "WebGLContextUtils.h"
#include "WebGLFormats.h"
#include "WebGLFramebuffer.h"
namespace mozilla {
using gl::GLContext;
using gl::GLFormats;
using webgl::EffectiveFormat;
using webgl::FormatInfo;
using webgl::ComponentType;
// Returns one of FLOAT, INT, UNSIGNED_INT.
// Fixed-points (normalized ints) are considered FLOAT.
static GLenum
@ -418,6 +425,103 @@ WebGL2Context::FramebufferTextureLayer(GLenum target, GLenum attachment,
fb->FramebufferTextureLayer(attachment, texture, level, layer);
}
JS::Value
WebGL2Context::GetFramebufferAttachmentParameter(JSContext* cx,
GLenum target,
GLenum attachment,
GLenum pname,
ErrorResult& rv)
{
if (IsContextLost())
return JS::NullValue();
// OpenGL ES 3.0.4 (August 27, 2014) 6.1. QUERYING GL STATE 240
// "getFramebufferAttachmentParamter returns information about attachments of a bound
// framebuffer object. target must be DRAW_FRAMEBUFFER, READ_FRAMEBUFFER, or
// FRAMEBUFFER."
if (!ValidateFramebufferTarget(target, "getFramebufferAttachmentParameter"))
return JS::NullValue();
// FRAMEBUFFER is equivalent to DRAW_FRAMEBUFFER.
if (target == LOCAL_GL_FRAMEBUFFER)
target = LOCAL_GL_DRAW_FRAMEBUFFER;
WebGLFramebuffer* boundFB = nullptr;
switch (target) {
case LOCAL_GL_DRAW_FRAMEBUFFER: boundFB = mBoundDrawFramebuffer; break;
case LOCAL_GL_READ_FRAMEBUFFER: boundFB = mBoundReadFramebuffer; break;
}
if (boundFB) {
return boundFB->GetAttachmentParameter(cx, attachment, pname, rv);
}
// Handle default FB
const gl::GLFormats& formats = gl->GetGLFormats();
GLenum internalFormat = LOCAL_GL_NONE;
/* If the default framebuffer is bound to target, then attachment must be BACK,
identifying the color buffer; DEPTH, identifying the depth buffer; or STENCIL,
identifying the stencil buffer. */
switch (attachment) {
case LOCAL_GL_BACK:
internalFormat = formats.color_texInternalFormat;
break;
case LOCAL_GL_DEPTH:
internalFormat = formats.depth;
break;
case LOCAL_GL_STENCIL:
internalFormat = formats.stencil;
break;
default:
ErrorInvalidEnum("getFramebufferAttachmentParameter: Can only query "
"attachment BACK, DEPTH, or STENCIL from default "
"framebuffer");
return JS::NullValue();
}
const FormatInfo* info = webgl::GetInfoBySizedFormat(internalFormat);
MOZ_RELEASE_ASSERT(info);
EffectiveFormat effectiveFormat = info->effectiveFormat;
switch (pname) {
case LOCAL_GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE:
return JS::Int32Value(LOCAL_GL_FRAMEBUFFER_DEFAULT);
case LOCAL_GL_FRAMEBUFFER_ATTACHMENT_RED_SIZE:
case LOCAL_GL_FRAMEBUFFER_ATTACHMENT_GREEN_SIZE:
case LOCAL_GL_FRAMEBUFFER_ATTACHMENT_BLUE_SIZE:
case LOCAL_GL_FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE:
case LOCAL_GL_FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE:
case LOCAL_GL_FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE:
return JS::Int32Value(webgl::GetComponentSize(effectiveFormat, pname));
case LOCAL_GL_FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE:
if (attachment == LOCAL_GL_DEPTH_STENCIL_ATTACHMENT &&
pname == LOCAL_GL_FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE)
{
ErrorInvalidOperation("getFramebufferAttachmentParameter: Querying "
"FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE against "
"DEPTH_STENCIL_ATTACHMENT is an error.");
return JS::NullValue();
}
return JS::Int32Value(webgl::GetComponentType(effectiveFormat));
case LOCAL_GL_FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING:
return JS::Int32Value(webgl::GetColorEncoding(effectiveFormat));
}
/* Any combinations of framebuffer type and pname not described above will generate an
INVALID_ENUM error. */
ErrorInvalidEnum("getFramebufferAttachmentParameter: Invalid combination of ");
return JS::NullValue();
}
// Map attachments intended for the default buffer, to attachments for a non-
// default buffer.
static bool

View File

@ -458,9 +458,9 @@ public:
}
GLenum GetError();
JS::Value GetFramebufferAttachmentParameter(JSContext* cx, GLenum target,
GLenum attachment, GLenum pname,
ErrorResult& rv);
virtual JS::Value GetFramebufferAttachmentParameter(JSContext* cx, GLenum target,
GLenum attachment, GLenum pname,
ErrorResult& rv);
void GetFramebufferAttachmentParameter(JSContext* cx, GLenum target,
GLenum attachment, GLenum pname,

View File

@ -809,5 +809,319 @@ FormatUsageAuthority::AddUnpackOption(GLenum unpackFormat, GLenum unpackType,
MOZ_ALWAYS_TRUE(didInsert);
}
////////////////////////////////////////////////////////////////////////////////
struct ComponentSizes
{
GLubyte redSize;
GLubyte greenSize;
GLubyte blueSize;
GLubyte alphaSize;
GLubyte depthSize;
GLubyte stencilSize;
};
static ComponentSizes kComponentSizes[] = {
// GLES 3.0.4, p128-129, "Required Texture Formats"
// "Texture and renderbuffer color formats"
{ 32, 32, 32, 32, 0, 0 }, // RGBA32I,
{ 32, 32, 32, 32, 0, 0 }, // RGBA32UI,
{ 16, 16, 16, 16, 0, 0 }, // RGBA16I,
{ 16, 16, 16, 16, 0, 0 }, // RGBA16UI,
{ 8, 8, 8, 8, 0, 0 }, // RGBA8,
{ 8, 8, 8, 8, 0, 0 }, // RGBA8I,
{ 8, 8, 8, 8, 0, 0 }, // RGBA8UI,
{ 8, 8, 8, 8, 0, 0 }, // SRGB8_ALPHA8,
{ 10, 10, 10, 2, 0, 0 }, // RGB10_A2,
{ 10, 10, 10, 2, 0, 0 }, // RGB10_A2UI,
{ 4, 4, 4, 4, 0, 0 }, // RGBA4,
{ 5, 5, 5, 1, 0, 0 }, // RGB5_A1,
{ 8, 8, 8, 0, 0, 0 }, // RGB8,
{ 8, 8, 8, 0, 0, 0 }, // RGB565,
{ 32, 32, 0, 0, 0, 0 }, // RG32I,
{ 32, 32, 0, 0, 0, 0 }, // RG32UI,
{ 16, 16, 0, 0, 0, 0 }, // RG16I,
{ 16, 16, 0, 0, 0, 0 }, // RG16UI,
{ 8, 8, 0, 0, 0, 0 }, // RG8,
{ 8, 8, 0, 0, 0, 0 }, // RG8I,
{ 8, 8, 0, 0, 0, 0 }, // RG8UI,
{ 32, 0, 0, 0, 0, 0 }, // R32I,
{ 32, 0, 0, 0, 0, 0 }, // R32UI,
{ 16, 0, 0, 0, 0, 0 }, // R16I,
{ 16, 0, 0, 0, 0, 0 }, // R16UI,
{ 8, 0, 0, 0, 0, 0 }, // R8,
{ 8, 0, 0, 0, 0, 0 }, // R8I,
{ 8, 0, 0, 0, 0, 0 }, // R8UI,
// "Texture-only color formats"
{ 32, 32, 32, 32, 0, 0 }, // RGBA32F,
{ 16, 16, 16, 16, 0, 0 }, // RGBA16F,
{ 8, 8, 8, 8, 0, 0 }, // RGBA8_SNORM,
{ 32, 32, 32, 0, 0, 0 }, // RGB32F,
{ 32, 32, 32, 0, 0, 0 }, // RGB32I,
{ 32, 32, 32, 0, 0, 0 }, // RGB32UI,
{ 16, 16, 16, 0, 0, 0 }, // RGB16F,
{ 16, 16, 16, 0, 0, 0 }, // RGB16I,
{ 16, 16, 16, 0, 0, 0 }, // RGB16UI,
{ 8, 8, 8, 0, 0, 0 }, // RGB8_SNORM,
{ 8, 8, 8, 0, 0, 0 }, // RGB8I,
{ 8, 8, 8, 0, 0, 0 }, // RGB8UI,
{ 8, 8, 8, 0, 0, 0 }, // SRGB8,
{ 11, 11, 11, 0, 0, 0 }, // R11F_G11F_B10F,
{ 9, 9, 9, 0, 0, 0 }, // RGB9_E5,
{ 32, 32, 0, 0, 0, 0 }, // RG32F,
{ 16, 16, 0, 0, 0, 0 }, // RG16F,
{ 8, 8, 0, 0, 0, 0 }, // RG8_SNORM,
{ 32, 0, 0, 0, 0, 0 }, // R32F,
{ 16, 0, 0, 0, 0, 0 }, // R16F,
{ 8, 0, 0, 0, 0, 0 }, // R8_SNORM,
// "Depth formats"
{ 0, 0, 0, 0, 32, 0 }, // DEPTH_COMPONENT32F,
{ 0, 0, 0, 0, 24, 0 }, // DEPTH_COMPONENT24,
{ 0, 0, 0, 0, 16, 0 }, // DEPTH_COMPONENT16,
// "Combined depth+stencil formats"
{ 0, 0, 0, 0, 32, 8 }, // DEPTH32F_STENCIL0,
{ 0, 0, 0, 0, 24, 8 }, // DEPTH24_STENCIL8,
// GLES 3.0.4, p205-206, "Required Renderbuffer Formats"
{ 0, 0, 0, 0, 0, 8 }, // STENCIL_INDEX8,
// GLES 3.0.4, p128, table 3.12.
{ 8, 8, 8, 8, 0, 0 }, // Luminance8Alpha8,
{ 8, 8, 8, 0, 0, 0 }, // Luminance8,
{ 0, 0, 0, 8, 0, 0 }, // Alpha8,
// GLES 3.0.4, p147, table 3.19
// GLES 3.0.4, p286+, $C.1 "ETC Compressed Texture Image Formats"
{ 8, 8, 8, 8, 0, 0 }, // COMPRESSED_R11_EAC,
{ 8, 8, 8, 8, 0, 0 }, // COMPRESSED_SIGNED_R11_EAC,
{ 8, 8, 8, 8, 0, 0 }, // COMPRESSED_RG11_EAC,
{ 8, 8, 8, 8, 0, 0 }, // COMPRESSED_SIGNED_RG11_EAC,
{ 8, 8, 8, 8, 0, 0 }, // COMPRESSED_RGB8_ETC2,
{ 8, 8, 8, 8, 0, 0 }, // COMPRESSED_SRGB8_ETC2,
{ 8, 8, 8, 8, 0, 0 }, // COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2,
{ 8, 8, 8, 8, 0, 0 }, // COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2,
{ 8, 8, 8, 8, 0, 0 }, // COMPRESSED_RGBA8_ETC2_EAC,
{ 8, 8, 8, 8, 0, 0 }, // COMPRESSED_SRGB8_ALPHA8_ETC2_EAC,
// AMD_compressed_ATC_texture
{ 8, 8, 8, 0, 0, 0 }, // ATC_RGB_AMD,
{ 8, 8, 8, 8, 0, 0 }, // ATC_RGBA_EXPLICIT_ALPHA_AMD,
{ 8, 8, 8, 8, 0, 0 }, // ATC_RGBA_INTERPOLATED_ALPHA_AMD,
// EXT_texture_compression_s3tc
{ 8, 8, 8, 0, 0, 0 }, // COMPRESSED_RGB_S3TC_DXT1,
{ 8, 8, 8, 8, 0, 0 }, // COMPRESSED_RGBA_S3TC_DXT1,
{ 8, 8, 8, 8, 0, 0 }, // COMPRESSED_RGBA_S3TC_DXT3,
{ 8, 8, 8, 8, 0, 0 }, // COMPRESSED_RGBA_S3TC_DXT5,
// IMG_texture_compression_pvrtc
{ 8, 8, 8, 0, 0, 0 }, // COMPRESSED_RGB_PVRTC_4BPPV1,
{ 8, 8, 8, 8, 0, 0 }, // COMPRESSED_RGBA_PVRTC_4BPPV1,
{ 8, 8, 8, 0, 0, 0 }, // COMPRESSED_RGB_PVRTC_2BPPV1,
{ 8, 8, 8, 8, 0, 0 }, // COMPRESSED_RGBA_PVRTC_2BPPV1,
// OES_compressed_ETC1_RGB8_texture
{ 8, 8, 8, 0, 0, 0 }, // ETC1_RGB8,
// OES_texture_float
{ 32, 32, 32, 32, 0, 0 }, // Luminance32FAlpha32F,
{ 32, 32, 32, 0, 0, 0 }, // Luminance32F,
{ 0, 0, 0, 32, 0, 0 }, // Alpha32F,
// OES_texture_half_float
{ 16, 16, 16, 16, 0, 0 }, // Luminance16FAlpha16F,
{ 16, 16, 16, 0, 0, 0 }, // Luminance16F,
{ 0, 0, 0, 16, 0, 0 }, // Alpha16F,
{ 0, } // MAX
};
GLint
GetComponentSize(EffectiveFormat format, GLenum component)
{
ComponentSizes compSize = kComponentSizes[(int) format];
switch (component) {
case LOCAL_GL_FRAMEBUFFER_ATTACHMENT_RED_SIZE:
case LOCAL_GL_RENDERBUFFER_RED_SIZE:
case LOCAL_GL_RED_BITS:
return compSize.redSize;
case LOCAL_GL_FRAMEBUFFER_ATTACHMENT_GREEN_SIZE:
case LOCAL_GL_RENDERBUFFER_GREEN_SIZE:
case LOCAL_GL_GREEN_BITS:
return compSize.greenSize;
case LOCAL_GL_FRAMEBUFFER_ATTACHMENT_BLUE_SIZE:
case LOCAL_GL_RENDERBUFFER_BLUE_SIZE:
case LOCAL_GL_BLUE_BITS:
return compSize.blueSize;
case LOCAL_GL_FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE:
case LOCAL_GL_RENDERBUFFER_ALPHA_SIZE:
case LOCAL_GL_ALPHA_BITS:
return compSize.alphaSize;
case LOCAL_GL_FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE:
case LOCAL_GL_RENDERBUFFER_DEPTH_SIZE:
case LOCAL_GL_DEPTH_BITS:
return compSize.depthSize;
case LOCAL_GL_FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE:
case LOCAL_GL_RENDERBUFFER_STENCIL_SIZE:
case LOCAL_GL_STENCIL_BITS:
return compSize.stencilSize;
}
return 0;
}
static GLenum kComponentTypes[] = {
// GLES 3.0.4, p128-129, "Required Texture Formats"
// "Texture and renderbuffer color formats"
LOCAL_GL_INT, // RGBA32I,
LOCAL_GL_UNSIGNED_INT, // RGBA32UI,
LOCAL_GL_INT, // RGBA16I,
LOCAL_GL_UNSIGNED_INT, // RGBA16UI,
LOCAL_GL_UNSIGNED_NORMALIZED, // RGBA8,
LOCAL_GL_INT, // RGBA8I,
LOCAL_GL_UNSIGNED_INT, // RGBA8UI,
LOCAL_GL_UNSIGNED_NORMALIZED, // SRGB8_ALPHA8,
LOCAL_GL_UNSIGNED_NORMALIZED, // RGB10_A2,
LOCAL_GL_UNSIGNED_INT, // RGB10_A2UI,
LOCAL_GL_UNSIGNED_NORMALIZED, // RGBA4,
LOCAL_GL_UNSIGNED_NORMALIZED, // RGB5_A1,
LOCAL_GL_UNSIGNED_NORMALIZED, // RGB8,
LOCAL_GL_UNSIGNED_NORMALIZED, // RGB565,
LOCAL_GL_INT, // RG32I,
LOCAL_GL_UNSIGNED_INT, // RG32UI,
LOCAL_GL_INT, // RG16I,
LOCAL_GL_UNSIGNED_INT, // RG16UI,
LOCAL_GL_UNSIGNED_NORMALIZED, // RG8,
LOCAL_GL_INT, // RG8I,
LOCAL_GL_UNSIGNED_INT, // RG8UI,
LOCAL_GL_INT, // R32I,
LOCAL_GL_UNSIGNED_INT, // R32UI,
LOCAL_GL_INT, // R16I,
LOCAL_GL_UNSIGNED_INT, // R16UI,
LOCAL_GL_UNSIGNED_NORMALIZED, // R8,
LOCAL_GL_INT, // R8I,
LOCAL_GL_UNSIGNED_INT, // R8UI,
// "Texture-only color formats"
LOCAL_GL_FLOAT, // RGBA32F,
LOCAL_GL_FLOAT, // RGBA16F,
LOCAL_GL_SIGNED_NORMALIZED, // RGBA8_SNORM,
LOCAL_GL_FLOAT, // RGB32F,
LOCAL_GL_INT, // RGB32I,
LOCAL_GL_UNSIGNED_INT, // RGB32UI,
LOCAL_GL_FLOAT, // RGB16F,
LOCAL_GL_INT, // RGB16I,
LOCAL_GL_UNSIGNED_INT, // RGB16UI,
LOCAL_GL_SIGNED_NORMALIZED, // RGB8_SNORM,
LOCAL_GL_INT, // RGB8I,
LOCAL_GL_UNSIGNED_INT, // RGB8UI,
LOCAL_GL_UNSIGNED_NORMALIZED, // SRGB8,
LOCAL_GL_FLOAT, // R11F_G11F_B10F,
LOCAL_GL_FLOAT, // RGB9_E5,
LOCAL_GL_FLOAT, // RG32F,
LOCAL_GL_FLOAT, // RG16F,
LOCAL_GL_SIGNED_NORMALIZED, // RG8_SNORM,
LOCAL_GL_FLOAT, // R32F,
LOCAL_GL_FLOAT, // R16F,
LOCAL_GL_SIGNED_NORMALIZED, // R8_SNORM,
// "Depth formats"
LOCAL_GL_FLOAT, // DEPTH_COMPONENT32F,
LOCAL_GL_UNSIGNED_NORMALIZED, // DEPTH_COMPONENT24,
LOCAL_GL_UNSIGNED_NORMALIZED, // DEPTH_COMPONENT16,
// "Combined depth+stencil formats"
LOCAL_GL_FLOAT, // DEPTH32F_STENCIL8,
LOCAL_GL_UNSIGNED_NORMALIZED, // DEPTH24_STENCIL8,
// GLES 3.0.4, p205-206, "Required Renderbuffer Formats"
LOCAL_GL_UNSIGNED_NORMALIZED, // STENCIL_INDEX8,
// GLES 3.0.4, p128, table 3.12.
LOCAL_GL_UNSIGNED_NORMALIZED, // Luminance8Alpha8,
LOCAL_GL_UNSIGNED_NORMALIZED, // Luminance8,
LOCAL_GL_UNSIGNED_NORMALIZED, // Alpha8,
// GLES 3.0.4, p147, table 3.19
// GLES 3.0.4, p286+, $C.1 "ETC Compressed Texture Image Formats"
LOCAL_GL_UNSIGNED_NORMALIZED, // COMPRESSED_R11_EAC,
LOCAL_GL_UNSIGNED_NORMALIZED, // COMPRESSED_SIGNED_R11_EAC,
LOCAL_GL_UNSIGNED_NORMALIZED, // COMPRESSED_RG11_EAC,
LOCAL_GL_UNSIGNED_NORMALIZED, // COMPRESSED_SIGNED_RG11_EAC,
LOCAL_GL_UNSIGNED_NORMALIZED, // COMPRESSED_RGB8_ETC2,
LOCAL_GL_UNSIGNED_NORMALIZED, // COMPRESSED_SRGB8_ETC2,
LOCAL_GL_UNSIGNED_NORMALIZED, // COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2,
LOCAL_GL_UNSIGNED_NORMALIZED, // COMPRESSED_SRGB8_PUNCHTHROUGH_ALPHA1_ETC2,
LOCAL_GL_UNSIGNED_NORMALIZED, // COMPRESSED_RGBA8_ETC2_EAC,
LOCAL_GL_UNSIGNED_NORMALIZED, // COMPRESSED_SRGB8_ALPHA8_ETC2_EAC,
// AMD_compressed_ATC_texture
LOCAL_GL_UNSIGNED_NORMALIZED, // ATC_RGB_AMD,
LOCAL_GL_UNSIGNED_NORMALIZED, // ATC_RGBA_EXPLICIT_ALPHA_AMD,
LOCAL_GL_UNSIGNED_NORMALIZED, // ATC_RGBA_INTERPOLATED_ALPHA_AMD,
// EXT_texture_compression_s3tc
LOCAL_GL_UNSIGNED_NORMALIZED, // COMPRESSED_RGB_S3TC_DXT1,
LOCAL_GL_UNSIGNED_NORMALIZED, // COMPRESSED_RGBA_S3TC_DXT1,
LOCAL_GL_UNSIGNED_NORMALIZED, // COMPRESSED_RGBA_S3TC_DXT3,
LOCAL_GL_UNSIGNED_NORMALIZED, // COMPRESSED_RGBA_S3TC_DXT5,
// IMG_texture_compression_pvrtc
LOCAL_GL_UNSIGNED_NORMALIZED, // COMPRESSED_RGB_PVRTC_4BPPV1,
LOCAL_GL_UNSIGNED_NORMALIZED, // COMPRESSED_RGBA_PVRTC_4BPPV1,
LOCAL_GL_UNSIGNED_NORMALIZED, // COMPRESSED_RGB_PVRTC_2BPPV1,
LOCAL_GL_UNSIGNED_NORMALIZED, // COMPRESSED_RGBA_PVRTC_2BPPV1,
// OES_compressed_ETC1_RGB8_texture
LOCAL_GL_UNSIGNED_NORMALIZED, // ETC1_RGB8,
// OES_texture_float
LOCAL_GL_FLOAT, // Luminance32FAlpha32F,
LOCAL_GL_FLOAT, // Luminance32F,
LOCAL_GL_FLOAT, // Alpha32F,
// OES_texture_half_float
LOCAL_GL_FLOAT, // Luminance16FAlpha16F,
LOCAL_GL_FLOAT, // Luminance16F,
LOCAL_GL_FLOAT, // Alpha16F,
LOCAL_GL_NONE // MAX
};
GLenum
GetComponentType(EffectiveFormat format)
{
return kComponentTypes[(int) format];
}
GLenum
GetColorEncoding(EffectiveFormat format)
{
const bool isSRGB = (GetFormatInfo(format)->colorComponentType ==
ComponentType::NormUIntSRGB);
return (isSRGB) ? LOCAL_GL_SRGB : LOCAL_GL_LINEAR;
}
} // namespace webgl
} // namespace mozilla

View File

@ -252,13 +252,21 @@ public:
EffectiveFormat effectiveFormat);
FormatUsageInfo* GetUsage(EffectiveFormat format);
FormatUsageInfo* GetUsage(const FormatInfo* format)
{
if (!format)
return nullptr;
return GetUsage(format->effectiveFormat);
}
};
////////////////////////////////////////////////////////////////////////////////
GLint GetComponentSize(EffectiveFormat format, GLenum component);
GLenum GetComponentType(EffectiveFormat format);
GLenum GetColorEncoding(EffectiveFormat format);
} // namespace webgl
} // namespace mozilla

View File

@ -433,6 +433,66 @@ WebGLFBAttachPoint::FinalizeAttachment(gl::GLContext* gl,
MOZ_CRASH();
}
JS::Value
WebGLFBAttachPoint::GetParameter(WebGLContext* context, GLenum pname)
{
// TODO: WebGLTexture and WebGLRenderbuffer should store FormatInfo instead of doing
// this dance every time.
const GLenum internalFormat = EffectiveInternalFormat().get();
const webgl::FormatInfo* info = webgl::GetInfoBySizedFormat(internalFormat);
MOZ_ASSERT(info);
WebGLTexture* tex = Texture();
switch (pname) {
case LOCAL_GL_FRAMEBUFFER_ATTACHMENT_RED_SIZE:
case LOCAL_GL_FRAMEBUFFER_ATTACHMENT_GREEN_SIZE:
case LOCAL_GL_FRAMEBUFFER_ATTACHMENT_BLUE_SIZE:
case LOCAL_GL_FRAMEBUFFER_ATTACHMENT_ALPHA_SIZE:
case LOCAL_GL_FRAMEBUFFER_ATTACHMENT_DEPTH_SIZE:
case LOCAL_GL_FRAMEBUFFER_ATTACHMENT_STENCIL_SIZE:
return JS::Int32Value(webgl::GetComponentSize(info->effectiveFormat, pname));
case LOCAL_GL_FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE:
return JS::Int32Value(webgl::GetComponentType(info->effectiveFormat));
case LOCAL_GL_FRAMEBUFFER_ATTACHMENT_COLOR_ENCODING:
return JS::Int32Value(webgl::GetColorEncoding(info->effectiveFormat));
case LOCAL_GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL:
if (tex) {
return JS::Int32Value(MipLevel());
}
break;
case LOCAL_GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE:
if (tex) {
int32_t face = 0;
if (tex->Target() == LOCAL_GL_TEXTURE_CUBE_MAP) {
face = ImageTarget().get();
}
return JS::Int32Value(face);
}
break;
case LOCAL_GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LAYER:
if (tex) {
int32_t layer = 0;
if (tex->Target() == LOCAL_GL_TEXTURE_2D_ARRAY ||
tex->Target() == LOCAL_GL_TEXTURE_3D)
{
layer = Layer();
}
return JS::Int32Value(layer);
}
break;
}
context->ErrorInvalidEnum("getFramebufferParameter: Invalid combination of "
"attachment and pname.");
return JS::NullValue();
}
////////////////////////////////////////////////////////////////////////////////
// WebGLFramebuffer
@ -987,6 +1047,110 @@ WebGLFramebuffer::ValidateForRead(const char* info, TexInternalFormat* const out
return true;
}
static bool
AttachmentsDontMatch(const WebGLFBAttachPoint& a, const WebGLFBAttachPoint& b)
{
if (a.Texture()) {
return (a.Texture() != b.Texture());
}
if (a.Renderbuffer()) {
return (a.Renderbuffer() != b.Renderbuffer());
}
return false;
}
JS::Value
WebGLFramebuffer::GetAttachmentParameter(JSContext* cx,
GLenum attachment,
GLenum pname,
ErrorResult& rv)
{
// "If a framebuffer object is bound to target, then attachment must be one of the
// attachment points of the framebuffer listed in table 4.6."
switch (attachment) {
case LOCAL_GL_DEPTH_ATTACHMENT:
case LOCAL_GL_DEPTH_STENCIL_ATTACHMENT:
break;
case LOCAL_GL_STENCIL_ATTACHMENT:
// "If attachment is DEPTH_STENCIL_ATTACHMENT, and different objects are bound to
// the depth and stencil attachment points of target, the query will fail and
// generate an INVALID_OPERATION error. If the same object is bound to both
// attachment points, information about that object will be returned."
// Does this mean it has to be the same level or layer? Because the queries are
// independent of level or layer.
if (AttachmentsDontMatch(DepthAttachment(), StencilAttachment())) {
mContext->ErrorInvalidOperation("getFramebufferAttachmentParameter: "
"DEPTH_ATTACHMENT and STENCIL_ATTACHMENT "
"have different objects bound.");
return JS::NullValue();
}
break;
default:
if (attachment < LOCAL_GL_COLOR_ATTACHMENT0 ||
attachment > mContext->LastColorAttachment())
{
mContext->ErrorInvalidEnum("getFramebufferAttachmentParameter: Can only "
"query COLOR_ATTACHMENTi, DEPTH_ATTACHMENT, "
"DEPTH_STENCIL_ATTACHMENT, or STENCIL_ATTACHMENT "
"on framebuffer.");
return JS::NullValue();
}
}
if (attachment == LOCAL_GL_DEPTH_STENCIL_ATTACHMENT &&
pname == LOCAL_GL_FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE)
{
mContext->ErrorInvalidOperation("getFramebufferAttachmentParameter: Querying "
"FRAMEBUFFER_ATTACHMENT_COMPONENT_TYPE against "
"DEPTH_STENCIL_ATTACHMENT is an error.");
return JS::NullValue();
}
GLenum objectType = LOCAL_GL_NONE;
auto& fba = GetAttachPoint(attachment);
if (fba.Texture()) {
objectType = LOCAL_GL_TEXTURE;
} else if (fba.Renderbuffer()) {
objectType = LOCAL_GL_RENDERBUFFER;
}
switch (pname) {
case LOCAL_GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE:
return JS::Int32Value(objectType);
case LOCAL_GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME:
if (objectType == LOCAL_GL_NONE) {
return JS::NullValue();
}
if (objectType == LOCAL_GL_RENDERBUFFER) {
const WebGLRenderbuffer* rb = fba.Renderbuffer();
return mContext->WebGLObjectAsJSValue(cx, rb, rv);
}
/* If the value of FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE is TEXTURE, then */
if (objectType == LOCAL_GL_TEXTURE) {
const WebGLTexture* tex = fba.Texture();
return mContext->WebGLObjectAsJSValue(cx, tex, rv);
}
break;
}
if (objectType == LOCAL_GL_NONE) {
mContext->ErrorInvalidOperation("getFramebufferAttachmentParameter: No "
"attachment at %s",
mContext->EnumName(attachment));
return JS::NullValue();
}
return fba.GetParameter(mContext, pname);
}
////////////////////////////////////////////////////////////////////////////////
// Goop.

View File

@ -62,7 +62,7 @@ public:
void SetTexImageLayer(WebGLTexture* tex, TexImageTarget target, GLint level,
GLint layer);
void SetRenderbuffer(WebGLRenderbuffer* rb);
const WebGLTexture* Texture() const {
return mTexturePtr;
}
@ -95,6 +95,8 @@ public:
void FinalizeAttachment(gl::GLContext* gl,
FBAttachment attachmentLoc) const;
JS::Value GetParameter(WebGLContext* context, GLenum pname);
};
class WebGLFramebuffer final
@ -225,6 +227,9 @@ public:
}
bool ValidateForRead(const char* info, TexInternalFormat* const out_format);
JS::Value GetAttachmentParameter(JSContext* cx, GLenum attachment, GLenum pname,
ErrorResult& rv);
};
} // namespace mozilla