зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1193070 - Implement GetFramebufferAttachmentParameter. r=jgilbert
This commit is contained in:
Родитель
716d1bd0e2
Коммит
66e4dad1c7
|
@ -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,
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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.
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
Загрузка…
Ссылка в новой задаче