summaryrefslogtreecommitdiffstats
path: root/gpu
diff options
context:
space:
mode:
authorgman@chromium.org <gman@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-08-23 18:46:30 +0000
committergman@chromium.org <gman@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-08-23 18:46:30 +0000
commit8e3e066579460f88a19e2e6e091c396f3bd851c3 (patch)
tree06df7936a1cba62db31ee09f437d1328ba21fbcf /gpu
parent83f49d2a539d5c2752958d8b6d7c9c6644aab62c (diff)
downloadchromium_src-8e3e066579460f88a19e2e6e091c396f3bd851c3.zip
chromium_src-8e3e066579460f88a19e2e6e091c396f3bd851c3.tar.gz
chromium_src-8e3e066579460f88a19e2e6e091c396f3bd851c3.tar.bz2
Adds support for EXT_framebuffer_multisample
I probably need more tests but in order to test I need to figure out how to init the system with different caps enabled from the unit tests and that's probably not a small amount of work so leaving that till later. TEST=some unit tests, ran conformance tests BUG=none Review URL: http://codereview.chromium.org/3122033 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@57081 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'gpu')
-rw-r--r--gpu/GLES2/gl2ext.h75
-rwxr-xr-xgpu/command_buffer/build_gles2_cmd_buffer.py27
-rw-r--r--gpu/command_buffer/client/gles2_c_lib_autogen.h12
-rw-r--r--gpu/command_buffer/client/gles2_cmd_helper_autogen.h16
-rw-r--r--gpu/command_buffer/client/gles2_implementation_autogen.h29
-rw-r--r--gpu/command_buffer/common/gles2_cmd_format_autogen.h135
-rw-r--r--gpu/command_buffer/common/gles2_cmd_format_test_autogen.h52
-rw-r--r--gpu/command_buffer/common/gles2_cmd_id_test_autogen.h4
-rw-r--r--gpu/command_buffer/common/gles2_cmd_ids_autogen.h2
-rw-r--r--gpu/command_buffer/service/context_group.cc12
-rw-r--r--gpu/command_buffer/service/context_group.h15
-rw-r--r--gpu/command_buffer/service/context_group_unittest.cc19
-rw-r--r--gpu/command_buffer/service/gles2_cmd_decoder.cc241
-rw-r--r--gpu/command_buffer/service/gles2_cmd_decoder_autogen.h62
-rw-r--r--gpu/command_buffer/service/gles2_cmd_decoder_unittest_1_autogen.h14
-rw-r--r--gpu/command_buffer/service/gles2_cmd_decoder_unittest_2_autogen.h4
-rw-r--r--gpu/command_buffer/service/gles2_cmd_validation_autogen.h1
-rw-r--r--gpu/command_buffer/service/gles2_cmd_validation_implementation_autogen.h7
18 files changed, 665 insertions, 62 deletions
diff --git a/gpu/GLES2/gl2ext.h b/gpu/GLES2/gl2ext.h
index 6c94efe..cae6500 100644
--- a/gpu/GLES2/gl2ext.h
+++ b/gpu/GLES2/gl2ext.h
@@ -798,6 +798,77 @@ typedef void (GL_APIENTRYP PFNGLSTARTTILINGQCOMPROC) (GLuint x, GLuint y, GLuint
typedef void (GL_APIENTRYP PFNGLENDTILINGQCOMPROC) (GLbitfield preserveMask);
#endif
+/* GL_EXT_framebuffer_multisample */
+#ifndef GL_EXT_framebuffer_multisample
+#define GL_EXT_framebuffer_multisample 1
+
+#ifndef GL_DRAW_FRAMEBUFFER_BINDING
+#define GL_DRAW_FRAMEBUFFER_BINDING 0x8CA6
+#endif
+#ifndef GL_DRAW_FRAMEBUFFER_BINDING_EXT
+#define GL_DRAW_FRAMEBUFFER_BINDING_EXT GL_DRAW_FRAMEBUFFER_BINDING
+#endif
+#ifndef GL_FRAMEBUFFER_BINDING
+#define GL_FRAMEBUFFER_BINDING 0x8CA6
+#endif
+#ifndef GL_FRAMEBUFFER_BINDING_EXT
+#define GL_FRAMEBUFFER_BINDING_EXT GL_FRAMEBUFFER_BINDING
+#endif
+#ifndef GL_RENDERBUFFER_BINDING
+#define GL_RENDERBUFFER_BINDING 0x8CA7
+#endif
+#ifndef GL_RENDERBUFFER_BINDING_EXT
+#define GL_RENDERBUFFER_BINDING_EXT GL_RENDERBUFFER_BINDING
+#endif
+#ifndef GL_READ_FRAMEBUFFER
+#define GL_READ_FRAMEBUFFER 0x8CA8
+#endif
+#ifndef GL_READ_FRAMEBUFFER_EXT
+#define GL_READ_FRAMEBUFFER_EXT GL_READ_FRAMEBUFFER
+#endif
+#ifndef GL_DRAW_FRAMEBUFFER
+#define GL_DRAW_FRAMEBUFFER 0x8CA9
+#endif
+#ifndef GL_DRAW_FRAMEBUFFER_EXT
+#define GL_DRAW_FRAMEBUFFER_EXT GL_DRAW_FRAMEBUFFER
+#endif
+#ifndef GL_READ_FRAMEBUFFER_BINDING
+#define GL_READ_FRAMEBUFFER_BINDING 0x8CAA
+#endif
+#ifndef GL_READ_FRAMEBUFFER_BINDING_EXT
+#define GL_READ_FRAMEBUFFER_BINDING_EXT GL_READ_FRAMEBUFFER_BINDING
+#endif
+#ifndef GL_RENDERBUFFER_SAMPLES
+#define GL_RENDERBUFFER_SAMPLES 0x8CAB
+#endif
+#ifndef GL_RENDERBUFFER_SAMPLES_EXT
+#define GL_RENDERBUFFER_SAMPLES_EXT GL_RENDERBUFFER_SAMPLES
+#endif
+#ifndef GL_MAX_SAMPLES
+#define GL_MAX_SAMPLES 0x8D57
+#endif
+#ifndef GL_MAX_SAMPLES_EXT
+#define GL_MAX_SAMPLES_EXT GL_MAX_SAMPLES
+#endif
+#ifndef GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE
+#define GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE 0x8D56
+#endif
+#ifndef GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_EXT
+#define GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_EXT GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE
+#endif
+
+#ifdef GL_GLEXT_PROTOTYPES
+#define glBlitFramebufferEXT GLES2_GET_FUN(BlitFramebufferEXT)
+#define glRenderbufferStorageMultisampleEXT GLES2_GET_FUN(RenderbufferStorageMultisampleEXT)
+#if !defined(GLES2_USE_CPP_BINDINGS)
+GL_APICALL void GL_APIENTRY glBlitFramebufferEXT (GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter);
+GL_APICALL void GL_APIENTRY glRenderbufferStorageMultisampleEXT (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height);
+#endif
+#endif
+typedef void (GL_APIENTRY PFNGLBLITFRAMEBUFFEREXT) (GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter);
+typedef void (GL_APIENTRY PFNGLRENDERBUFFERSTORAGEMULTISAMPLEEXT) (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height);
+#endif
+
/* GL_CHROMIUM_map_sub */
#ifndef GL_CHROMIUM_map_sub
#define GL_CHROMIUM_map_sub 1
@@ -818,14 +889,12 @@ GL_APICALL void GL_APIENTRY glUnmapBufferSubData (const void* mem);
GL_APICALL void* GL_APIENTRY glMapTexSubImage2D (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, GLenum access);
GL_APICALL void GL_APIENTRY glUnmapTexSubImage2D (const void* mem);
#endif
-#else
+#endif
typedef void* (GL_APIENTRYP PFNGLMAPBUFFERSUBDATA) (GLuint target, GLintptr offset, GLsizeiptr size, GLenum access);
typedef void (GL_APIENTRYP PFNGLUNMAPBUFFERSUBDATA) (const void* mem);
typedef void* (GL_APIENTRYP PFNGLMAPTEXSUBIMAGE2D) (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, GLenum access);
typedef void (GL_APIENTRYP PFNGLUNMAPTEXSUBIMAGE2D) (const void* mem);
#endif
-#endif
-
#ifdef __cplusplus
}
diff --git a/gpu/command_buffer/build_gles2_cmd_buffer.py b/gpu/command_buffer/build_gles2_cmd_buffer.py
index f747f7a..05310a4 100755
--- a/gpu/command_buffer/build_gles2_cmd_buffer.py
+++ b/gpu/command_buffer/build_gles2_cmd_buffer.py
@@ -175,6 +175,8 @@ GL_APICALL void GL_APIENTRY glVertexAttrib4f (GLuint indx, GLfloat x, GL
GL_APICALL void GL_APIENTRY glVertexAttrib4fv (GLuint indx, const GLfloat* values);
GL_APICALL void GL_APIENTRY glVertexAttribPointer (GLuint indx, GLintVertexAttribSize size, GLenumVertexAttribType type, GLboolean normalized, GLsizei stride, const void* ptr);
GL_APICALL void GL_APIENTRY glViewport (GLint x, GLint y, GLsizei width, GLsizei height);
+GL_APICALL void GL_APIENTRY glBlitFramebufferEXT (GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenumBlitFilter filter);
+GL_APICALL void GL_APIENTRY glRenderbufferStorageMultisampleEXT (GLenumRenderBufferTarget target, GLsizei samples, GLenumRenderBufferFormat internalformat, GLsizei width, GLsizei height);
// Non-GL commands.
GL_APICALL void GL_APIENTRY glSwapBuffers (void);
GL_APICALL GLuint GL_APIENTRY glGetMaxValueInBuffer (GLidBuffer buffer_id, GLsizei count, GLenumGetMaxIndexType type, GLuint offset);
@@ -383,18 +385,30 @@ _CMD_ID_TABLE = {
'CommandBufferEnable': 442,
'CompressedTexImage2DBucket': 443,
'CompressedTexSubImage2DBucket': 444,
+ 'RenderbufferStorageMultisampleEXT': 445,
+ 'BlitFramebufferEXT': 446,
}
# This is a list of enum names and their valid values. It is used to map
# GLenum arguments to a specific set of valid values.
_ENUM_LISTS = {
+ 'BlitFilter': {
+ 'type': 'GLenum',
+ 'valid': [
+ 'GL_NEAREST',
+ 'GL_LINEAR',
+ ],
+ 'invalid': [
+ 'GL_LINEAR_MIPMAP_LINEAR',
+ ],
+ },
'FrameBufferTarget': {
'type': 'GLenum',
'valid': [
'GL_FRAMEBUFFER',
],
'invalid': [
- 'GL_RENDERBUFFER',
+ 'GL_READ_FRAMEBUFFER' ,
],
},
'RenderBufferTarget': {
@@ -1030,6 +1044,10 @@ _FUNCTION_INFO = {
'decoder_func': 'DoBindTexture',
'gen_func': 'GenTextures',
},
+ 'BlitFramebufferEXT': {
+ 'decoder_func': 'DoBlitFramebufferEXT',
+ 'unit_test': False,
+ },
'BufferData': {'type': 'Manual', 'immediate': True},
'BufferSubData': {'type': 'Data', 'decoder_func': 'DoBufferSubData'},
'CheckFramebufferStatus': {
@@ -1355,6 +1373,12 @@ _FUNCTION_INFO = {
'gl_test_func': 'glRenderbufferStorageEXT',
'expectation': False,
},
+ 'RenderbufferStorageMultisampleEXT': {
+ 'decoder_func': 'DoRenderbufferStorageMultisample',
+ 'gl_test_func': 'glRenderbufferStorageMultisampleEXT',
+ 'expectation': False,
+ 'unit_test': False,
+ },
'ReadPixels': {
'cmd_comment':
'// ReadPixels has the result separated from the pixel buffer so that\n'
@@ -1623,7 +1647,6 @@ class CHeaderWriter(CWriter):
def __init__(self, filename, file_comment = None):
CWriter.__init__(self, filename)
-
base = os.path.dirname(
os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
hpath = os.path.abspath(filename)[len(base) + 1:]
diff --git a/gpu/command_buffer/client/gles2_c_lib_autogen.h b/gpu/command_buffer/client/gles2_c_lib_autogen.h
index bae1f9e..0aca957 100644
--- a/gpu/command_buffer/client/gles2_c_lib_autogen.h
+++ b/gpu/command_buffer/client/gles2_c_lib_autogen.h
@@ -500,6 +500,18 @@ void GLES2VertexAttribPointer(
void GLES2Viewport(GLint x, GLint y, GLsizei width, GLsizei height) {
gles2::GetGLContext()->Viewport(x, y, width, height);
}
+void GLES2BlitFramebufferEXT(
+ GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0,
+ GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter) {
+ gles2::GetGLContext()->BlitFramebufferEXT(
+ srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter);
+}
+void GLES2RenderbufferStorageMultisampleEXT(
+ GLenum target, GLsizei samples, GLenum internalformat, GLsizei width,
+ GLsizei height) {
+ gles2::GetGLContext()->RenderbufferStorageMultisampleEXT(
+ target, samples, internalformat, width, height);
+}
void GLES2SwapBuffers() {
gles2::GetGLContext()->SwapBuffers();
}
diff --git a/gpu/command_buffer/client/gles2_cmd_helper_autogen.h b/gpu/command_buffer/client/gles2_cmd_helper_autogen.h
index aa2270b..0815df3 100644
--- a/gpu/command_buffer/client/gles2_cmd_helper_autogen.h
+++ b/gpu/command_buffer/client/gles2_cmd_helper_autogen.h
@@ -1131,6 +1131,22 @@
c.Init(x, y, width, height);
}
+ void BlitFramebufferEXT(
+ GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0,
+ GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter) {
+ gles2::BlitFramebufferEXT& c = GetCmdSpace<gles2::BlitFramebufferEXT>();
+ c.Init(
+ srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter);
+ }
+
+ void RenderbufferStorageMultisampleEXT(
+ GLenum target, GLsizei samples, GLenum internalformat, GLsizei width,
+ GLsizei height) {
+ gles2::RenderbufferStorageMultisampleEXT& c =
+ GetCmdSpace<gles2::RenderbufferStorageMultisampleEXT>();
+ c.Init(target, samples, internalformat, width, height);
+ }
+
void SwapBuffers() {
gles2::SwapBuffers& c = GetCmdSpace<gles2::SwapBuffers>();
c.Init();
diff --git a/gpu/command_buffer/client/gles2_implementation_autogen.h b/gpu/command_buffer/client/gles2_implementation_autogen.h
index 8dd914b..872bcf63 100644
--- a/gpu/command_buffer/client/gles2_implementation_autogen.h
+++ b/gpu/command_buffer/client/gles2_implementation_autogen.h
@@ -770,6 +770,35 @@ void Viewport(GLint x, GLint y, GLsizei width, GLsizei height) {
helper_->Viewport(x, y, width, height);
}
+void BlitFramebufferEXT(
+ GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0,
+ GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter) {
+ helper_->BlitFramebufferEXT(
+ srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter);
+}
+
+void RenderbufferStorageMultisampleEXT(
+ GLenum target, GLsizei samples, GLenum internalformat, GLsizei width,
+ GLsizei height) {
+ if (samples < 0) {
+ SetGLError(
+ GL_INVALID_VALUE, "glRenderbufferStorageMultisampleEXT: samples < 0");
+ return;
+ }
+ if (width < 0) {
+ SetGLError(
+ GL_INVALID_VALUE, "glRenderbufferStorageMultisampleEXT: width < 0");
+ return;
+ }
+ if (height < 0) {
+ SetGLError(
+ GL_INVALID_VALUE, "glRenderbufferStorageMultisampleEXT: height < 0");
+ return;
+ }
+ helper_->RenderbufferStorageMultisampleEXT(
+ target, samples, internalformat, width, height);
+}
+
void SwapBuffers();
GLuint GetMaxValueInBuffer(
diff --git a/gpu/command_buffer/common/gles2_cmd_format_autogen.h b/gpu/command_buffer/common/gles2_cmd_format_autogen.h
index eb46619..badcffa 100644
--- a/gpu/command_buffer/common/gles2_cmd_format_autogen.h
+++ b/gpu/command_buffer/common/gles2_cmd_format_autogen.h
@@ -8321,6 +8321,141 @@ COMPILE_ASSERT(offsetof(Viewport, width) == 12,
COMPILE_ASSERT(offsetof(Viewport, height) == 16,
OffsetOf_Viewport_height_not_16);
+struct BlitFramebufferEXT {
+ typedef BlitFramebufferEXT ValueType;
+ static const CommandId kCmdId = kBlitFramebufferEXT;
+ static const cmd::ArgFlags kArgFlags = cmd::kFixed;
+
+ static uint32 ComputeSize() {
+ return static_cast<uint32>(sizeof(ValueType)); // NOLINT
+ }
+
+ void SetHeader() {
+ header.SetCmd<ValueType>();
+ }
+
+ void Init(
+ GLint _srcX0, GLint _srcY0, GLint _srcX1, GLint _srcY1, GLint _dstX0,
+ GLint _dstY0, GLint _dstX1, GLint _dstY1, GLbitfield _mask,
+ GLenum _filter) {
+ SetHeader();
+ srcX0 = _srcX0;
+ srcY0 = _srcY0;
+ srcX1 = _srcX1;
+ srcY1 = _srcY1;
+ dstX0 = _dstX0;
+ dstY0 = _dstY0;
+ dstX1 = _dstX1;
+ dstY1 = _dstY1;
+ mask = _mask;
+ filter = _filter;
+ }
+
+ void* Set(
+ void* cmd, GLint _srcX0, GLint _srcY0, GLint _srcX1, GLint _srcY1,
+ GLint _dstX0, GLint _dstY0, GLint _dstX1, GLint _dstY1, GLbitfield _mask,
+ GLenum _filter) {
+ static_cast<ValueType*>(
+ cmd)->Init(
+ _srcX0, _srcY0, _srcX1, _srcY1, _dstX0, _dstY0, _dstX1, _dstY1,
+ _mask, _filter);
+ return NextCmdAddress<ValueType>(cmd);
+ }
+
+ gpu::CommandHeader header;
+ int32 srcX0;
+ int32 srcY0;
+ int32 srcX1;
+ int32 srcY1;
+ int32 dstX0;
+ int32 dstY0;
+ int32 dstX1;
+ int32 dstY1;
+ uint32 mask;
+ uint32 filter;
+};
+
+COMPILE_ASSERT(sizeof(BlitFramebufferEXT) == 44,
+ Sizeof_BlitFramebufferEXT_is_not_44);
+COMPILE_ASSERT(offsetof(BlitFramebufferEXT, header) == 0,
+ OffsetOf_BlitFramebufferEXT_header_not_0);
+COMPILE_ASSERT(offsetof(BlitFramebufferEXT, srcX0) == 4,
+ OffsetOf_BlitFramebufferEXT_srcX0_not_4);
+COMPILE_ASSERT(offsetof(BlitFramebufferEXT, srcY0) == 8,
+ OffsetOf_BlitFramebufferEXT_srcY0_not_8);
+COMPILE_ASSERT(offsetof(BlitFramebufferEXT, srcX1) == 12,
+ OffsetOf_BlitFramebufferEXT_srcX1_not_12);
+COMPILE_ASSERT(offsetof(BlitFramebufferEXT, srcY1) == 16,
+ OffsetOf_BlitFramebufferEXT_srcY1_not_16);
+COMPILE_ASSERT(offsetof(BlitFramebufferEXT, dstX0) == 20,
+ OffsetOf_BlitFramebufferEXT_dstX0_not_20);
+COMPILE_ASSERT(offsetof(BlitFramebufferEXT, dstY0) == 24,
+ OffsetOf_BlitFramebufferEXT_dstY0_not_24);
+COMPILE_ASSERT(offsetof(BlitFramebufferEXT, dstX1) == 28,
+ OffsetOf_BlitFramebufferEXT_dstX1_not_28);
+COMPILE_ASSERT(offsetof(BlitFramebufferEXT, dstY1) == 32,
+ OffsetOf_BlitFramebufferEXT_dstY1_not_32);
+COMPILE_ASSERT(offsetof(BlitFramebufferEXT, mask) == 36,
+ OffsetOf_BlitFramebufferEXT_mask_not_36);
+COMPILE_ASSERT(offsetof(BlitFramebufferEXT, filter) == 40,
+ OffsetOf_BlitFramebufferEXT_filter_not_40);
+
+struct RenderbufferStorageMultisampleEXT {
+ typedef RenderbufferStorageMultisampleEXT ValueType;
+ static const CommandId kCmdId = kRenderbufferStorageMultisampleEXT;
+ static const cmd::ArgFlags kArgFlags = cmd::kFixed;
+
+ static uint32 ComputeSize() {
+ return static_cast<uint32>(sizeof(ValueType)); // NOLINT
+ }
+
+ void SetHeader() {
+ header.SetCmd<ValueType>();
+ }
+
+ void Init(
+ GLenum _target, GLsizei _samples, GLenum _internalformat, GLsizei _width,
+ GLsizei _height) {
+ SetHeader();
+ target = _target;
+ samples = _samples;
+ internalformat = _internalformat;
+ width = _width;
+ height = _height;
+ }
+
+ void* Set(
+ void* cmd, GLenum _target, GLsizei _samples, GLenum _internalformat,
+ GLsizei _width, GLsizei _height) {
+ static_cast<ValueType*>(
+ cmd)->Init(_target, _samples, _internalformat, _width, _height);
+ return NextCmdAddress<ValueType>(cmd);
+ }
+
+ gpu::CommandHeader header;
+ uint32 target;
+ int32 samples;
+ uint32 internalformat;
+ int32 width;
+ int32 height;
+};
+
+COMPILE_ASSERT(sizeof(RenderbufferStorageMultisampleEXT) == 24,
+ Sizeof_RenderbufferStorageMultisampleEXT_is_not_24);
+COMPILE_ASSERT(offsetof(RenderbufferStorageMultisampleEXT, header) == 0,
+ OffsetOf_RenderbufferStorageMultisampleEXT_header_not_0);
+COMPILE_ASSERT(offsetof(RenderbufferStorageMultisampleEXT, target) == 4,
+ OffsetOf_RenderbufferStorageMultisampleEXT_target_not_4);
+COMPILE_ASSERT(offsetof(RenderbufferStorageMultisampleEXT, samples) == 8,
+ OffsetOf_RenderbufferStorageMultisampleEXT_samples_not_8);
+COMPILE_ASSERT(
+ offsetof(RenderbufferStorageMultisampleEXT, internalformat) == 12,
+ OffsetOf_RenderbufferStorageMultisampleEXT_internalformat_not_12); // NOLINT
+COMPILE_ASSERT(offsetof(RenderbufferStorageMultisampleEXT, width) == 16,
+ OffsetOf_RenderbufferStorageMultisampleEXT_width_not_16);
+COMPILE_ASSERT(offsetof(RenderbufferStorageMultisampleEXT, height) == 20,
+ OffsetOf_RenderbufferStorageMultisampleEXT_height_not_20);
+
struct SwapBuffers {
typedef SwapBuffers ValueType;
static const CommandId kCmdId = kSwapBuffers;
diff --git a/gpu/command_buffer/common/gles2_cmd_format_test_autogen.h b/gpu/command_buffer/common/gles2_cmd_format_test_autogen.h
index 9969c2f..177b084 100644
--- a/gpu/command_buffer/common/gles2_cmd_format_test_autogen.h
+++ b/gpu/command_buffer/common/gles2_cmd_format_test_autogen.h
@@ -3288,6 +3288,58 @@ TEST(GLES2FormatTest, Viewport) {
EXPECT_EQ(static_cast<GLsizei>(14), cmd.height);
}
+TEST(GLES2FormatTest, BlitFramebufferEXT) {
+ BlitFramebufferEXT cmd = { { 0 } };
+ void* next_cmd = cmd.Set(
+ &cmd,
+ static_cast<GLint>(11),
+ static_cast<GLint>(12),
+ static_cast<GLint>(13),
+ static_cast<GLint>(14),
+ static_cast<GLint>(15),
+ static_cast<GLint>(16),
+ static_cast<GLint>(17),
+ static_cast<GLint>(18),
+ static_cast<GLbitfield>(19),
+ static_cast<GLenum>(20));
+ EXPECT_EQ(static_cast<uint32>(BlitFramebufferEXT::kCmdId),
+ cmd.header.command);
+ EXPECT_EQ(sizeof(cmd), cmd.header.size * 4u);
+ EXPECT_EQ(static_cast<char*>(next_cmd),
+ reinterpret_cast<char*>(&cmd) + sizeof(cmd));
+ EXPECT_EQ(static_cast<GLint>(11), cmd.srcX0);
+ EXPECT_EQ(static_cast<GLint>(12), cmd.srcY0);
+ EXPECT_EQ(static_cast<GLint>(13), cmd.srcX1);
+ EXPECT_EQ(static_cast<GLint>(14), cmd.srcY1);
+ EXPECT_EQ(static_cast<GLint>(15), cmd.dstX0);
+ EXPECT_EQ(static_cast<GLint>(16), cmd.dstY0);
+ EXPECT_EQ(static_cast<GLint>(17), cmd.dstX1);
+ EXPECT_EQ(static_cast<GLint>(18), cmd.dstY1);
+ EXPECT_EQ(static_cast<GLbitfield>(19), cmd.mask);
+ EXPECT_EQ(static_cast<GLenum>(20), cmd.filter);
+}
+
+TEST(GLES2FormatTest, RenderbufferStorageMultisampleEXT) {
+ RenderbufferStorageMultisampleEXT cmd = { { 0 } };
+ void* next_cmd = cmd.Set(
+ &cmd,
+ static_cast<GLenum>(11),
+ static_cast<GLsizei>(12),
+ static_cast<GLenum>(13),
+ static_cast<GLsizei>(14),
+ static_cast<GLsizei>(15));
+ EXPECT_EQ(static_cast<uint32>(RenderbufferStorageMultisampleEXT::kCmdId),
+ cmd.header.command);
+ EXPECT_EQ(sizeof(cmd), cmd.header.size * 4u);
+ EXPECT_EQ(static_cast<char*>(next_cmd),
+ reinterpret_cast<char*>(&cmd) + sizeof(cmd));
+ EXPECT_EQ(static_cast<GLenum>(11), cmd.target);
+ EXPECT_EQ(static_cast<GLsizei>(12), cmd.samples);
+ EXPECT_EQ(static_cast<GLenum>(13), cmd.internalformat);
+ EXPECT_EQ(static_cast<GLsizei>(14), cmd.width);
+ EXPECT_EQ(static_cast<GLsizei>(15), cmd.height);
+}
+
TEST(GLES2FormatTest, SwapBuffers) {
SwapBuffers cmd = { { 0 } };
void* next_cmd = cmd.Set(
diff --git a/gpu/command_buffer/common/gles2_cmd_id_test_autogen.h b/gpu/command_buffer/common/gles2_cmd_id_test_autogen.h
index a2890cc..7fc268d 100644
--- a/gpu/command_buffer/common/gles2_cmd_id_test_autogen.h
+++ b/gpu/command_buffer/common/gles2_cmd_id_test_autogen.h
@@ -377,6 +377,10 @@ TEST(GLES2CommandIdTest, CommandIdsMatch) {
GLES2_VertexAttribPointer_kCmdId_mismatch);
COMPILE_ASSERT(Viewport::kCmdId == 430,
GLES2_Viewport_kCmdId_mismatch);
+ COMPILE_ASSERT(BlitFramebufferEXT::kCmdId == 446,
+ GLES2_BlitFramebufferEXT_kCmdId_mismatch);
+ COMPILE_ASSERT(RenderbufferStorageMultisampleEXT::kCmdId == 445,
+ GLES2_RenderbufferStorageMultisampleEXT_kCmdId_mismatch);
COMPILE_ASSERT(SwapBuffers::kCmdId == 431,
GLES2_SwapBuffers_kCmdId_mismatch);
COMPILE_ASSERT(GetMaxValueInBuffer::kCmdId == 438,
diff --git a/gpu/command_buffer/common/gles2_cmd_ids_autogen.h b/gpu/command_buffer/common/gles2_cmd_ids_autogen.h
index 9308fe0..f9ae357 100644
--- a/gpu/command_buffer/common/gles2_cmd_ids_autogen.h
+++ b/gpu/command_buffer/common/gles2_cmd_ids_autogen.h
@@ -197,6 +197,8 @@
OP(CommandBufferEnable) /* 442 */ \
OP(CompressedTexImage2DBucket) /* 443 */ \
OP(CompressedTexSubImage2DBucket) /* 444 */ \
+ OP(RenderbufferStorageMultisampleEXT) /* 445 */ \
+ OP(BlitFramebufferEXT) /* 446 */ \
enum CommandId {
kStartPoint = cmd::kLastCommonId, // All GLES2 commands start after this.
diff --git a/gpu/command_buffer/service/context_group.cc b/gpu/command_buffer/service/context_group.cc
index c0a9a98..5cedbbd 100644
--- a/gpu/command_buffer/service/context_group.cc
+++ b/gpu/command_buffer/service/context_group.cc
@@ -142,6 +142,18 @@ bool ContextGroup::Initialize() {
}
}
+ // Check for multisample support
+ if (strstr(extensions, "GL_EXT_framebuffer_multisample")) {
+ extension_flags_.ext_framebuffer_multisample = true;
+ validators_.frame_buffer_target.AddValue(GL_READ_FRAMEBUFFER_EXT);
+ validators_.frame_buffer_target.AddValue(GL_DRAW_FRAMEBUFFER_EXT);
+ validators_.g_l_state.AddValue(GL_READ_FRAMEBUFFER_BINDING_EXT);
+ validators_.g_l_state.AddValue(GL_DRAW_FRAMEBUFFER_BINDING_EXT);
+ validators_.render_buffer_parameter.AddValue(GL_MAX_SAMPLES_EXT);
+ AddExtensionString("GL_EXT_framebuffer_multisample");
+ AddExtensionString("GL_EXT_framebuffer_blit");
+ }
+
// TODO(gman): Add support for these extensions.
// GL_OES_depth24
// GL_OES_depth32
diff --git a/gpu/command_buffer/service/context_group.h b/gpu/command_buffer/service/context_group.h
index a38f369..77b1c7a 100644
--- a/gpu/command_buffer/service/context_group.h
+++ b/gpu/command_buffer/service/context_group.h
@@ -30,6 +30,14 @@ class TextureManager;
// resources.
class ContextGroup {
public:
+ struct ExtensionFlags {
+ ExtensionFlags()
+ : ext_framebuffer_multisample(false) {
+ }
+
+ bool ext_framebuffer_multisample;
+ };
+
ContextGroup();
~ContextGroup();
@@ -101,6 +109,10 @@ class ContextGroup {
return extensions_;
}
+ const ExtensionFlags& extension_flags() const {
+ return extension_flags_;
+ }
+
private:
void AddExtensionString(const std::string& str);
@@ -135,6 +147,9 @@ class ContextGroup {
// The extensions string returned by glGetString(GL_EXTENSIONS);
std::string extensions_;
+ // Flags for some extensions
+ ExtensionFlags extension_flags_;
+
DISALLOW_COPY_AND_ASSIGN(ContextGroup);
};
diff --git a/gpu/command_buffer/service/context_group_unittest.cc b/gpu/command_buffer/service/context_group_unittest.cc
index 34c8adc..c8717c4 100644
--- a/gpu/command_buffer/service/context_group_unittest.cc
+++ b/gpu/command_buffer/service/context_group_unittest.cc
@@ -122,6 +122,7 @@ TEST_F(ContextGroupTest, Basic) {
EXPECT_TRUE(group_.texture_manager() == NULL);
EXPECT_TRUE(group_.program_manager() == NULL);
EXPECT_TRUE(group_.shader_manager() == NULL);
+ EXPECT_FALSE(group_.extension_flags().ext_framebuffer_multisample);
}
TEST_F(ContextGroupTest, InitializeNoExtensions) {
@@ -286,6 +287,24 @@ TEST_F(ContextGroupTest, InitializeOES_texture_half_float_linearGLES2) {
EXPECT_TRUE(group_.validators()->pixel_type.IsValid(GL_HALF_FLOAT_OES));
}
+TEST_F(ContextGroupTest, InitializeEXT_framebuffer_multisample) {
+ SetupInitExpectations("GL_EXT_framebuffer_multisample");
+ group_.Initialize();
+ EXPECT_TRUE(group_.extension_flags().ext_framebuffer_multisample);
+ EXPECT_THAT(group_.extensions(), HasSubstr("GL_EXT_framebuffer_multisample"));
+ EXPECT_THAT(group_.extensions(), HasSubstr("GL_EXT_framebuffer_blit"));
+ EXPECT_TRUE(group_.validators()->frame_buffer_target.IsValid(
+ GL_READ_FRAMEBUFFER_EXT));
+ EXPECT_TRUE(group_.validators()->frame_buffer_target.IsValid(
+ GL_DRAW_FRAMEBUFFER_EXT));
+ EXPECT_TRUE(group_.validators()->g_l_state.IsValid(
+ GL_READ_FRAMEBUFFER_BINDING_EXT));
+ EXPECT_TRUE(group_.validators()->g_l_state.IsValid(
+ GL_DRAW_FRAMEBUFFER_BINDING_EXT));
+ EXPECT_TRUE(group_.validators()->render_buffer_parameter.IsValid(
+ GL_MAX_SAMPLES_EXT));
+}
+
} // namespace gles2
} // namespace gpu
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder.cc b/gpu/command_buffer/service/gles2_cmd_decoder.cc
index ab36100..639ba86 100644
--- a/gpu/command_buffer/service/gles2_cmd_decoder.cc
+++ b/gpu/command_buffer/service/gles2_cmd_decoder.cc
@@ -556,11 +556,13 @@ class GLES2DecoderImpl : public base::SupportsWeakPtr<GLES2DecoderImpl>,
virtual void SetSwapBuffersCallback(Callback0::Type* callback);
+ // Restores the current state to the user's settings.
+ void RestoreCurrentFramebufferBindings();
+ void RestoreCurrentRenderbufferBindings();
+ void RestoreCurrentTexture2DBindings();
+
private:
friend class ScopedGLErrorSuppressor;
- friend class ScopedTexture2DBinder;
- friend class ScopedFrameBufferBinder;
- friend class ScopedRenderBufferBinder;
friend class ScopedDefaultGLContext;
friend class RenderBuffer;
friend class FrameBuffer;
@@ -635,7 +637,7 @@ class GLES2DecoderImpl : public base::SupportsWeakPtr<GLES2DecoderImpl>,
// Get the size (in pixels) of the currently bound frame buffer (either FBO
// or regular back buffer).
- gfx::Size GetBoundFrameBufferSize();
+ gfx::Size GetBoundReadFrameBufferSize();
// Wrapper for CompressedTexImage2D commands.
error::Error DoCompressedTexImage2D(
@@ -848,7 +850,8 @@ class GLES2DecoderImpl : public base::SupportsWeakPtr<GLES2DecoderImpl>,
GLuint client_id, const char* data, uint32 data_size);
// Clears any uncleared render buffers attached to the given frame buffer.
- void ClearUnclearedRenderbuffers(FramebufferManager::FramebufferInfo* info);
+ void ClearUnclearedRenderbuffers(
+ GLenum target, FramebufferManager::FramebufferInfo* info);
// Remembers the state of some capabilities.
void SetCapabilityState(GLenum cap, bool enabled);
@@ -897,6 +900,12 @@ class GLES2DecoderImpl : public base::SupportsWeakPtr<GLES2DecoderImpl>,
// Wrapper for glBindTexture since we need to track the current targets.
void DoBindTexture(GLenum target, GLuint texture);
+ // Wrapper for glBlitFramebufferEXT.
+ void DoBlitFramebufferEXT(
+ GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
+ GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
+ GLbitfield mask, GLenum filter);
+
// Wrapper for glBufferData.
void DoBufferData(
GLenum target, GLsizeiptr size, const GLvoid * data, GLenum usage);
@@ -1010,6 +1019,11 @@ class GLES2DecoderImpl : public base::SupportsWeakPtr<GLES2DecoderImpl>,
void DoRenderbufferStorage(
GLenum target, GLenum internalformat, GLsizei width, GLsizei height);
+ // Wrapper for glRenderbufferStorageMultisampleEXT.
+ void DoRenderbufferStorageMultisample(
+ GLenum target, GLsizei samples, GLenum internalformat,
+ GLsizei width, GLsizei height);
+
// Wrapper for glReleaseShaderCompiler.
void DoReleaseShaderCompiler() { }
@@ -1115,6 +1129,25 @@ class GLES2DecoderImpl : public base::SupportsWeakPtr<GLES2DecoderImpl>,
return (info && !info->IsDeleted()) ? info : NULL;
}
+ // Gets the framebuffer info for a particular target.
+ FramebufferManager::FramebufferInfo* GetFramebufferInfoForTarget(
+ GLenum target) {
+ FramebufferManager::FramebufferInfo* info = NULL;
+ switch (target) {
+ case GL_FRAMEBUFFER:
+ case GL_DRAW_FRAMEBUFFER:
+ info = bound_draw_framebuffer_;
+ break;
+ case GL_READ_FRAMEBUFFER:
+ info = bound_read_framebuffer_;
+ break;
+ default:
+ NOTREACHED();
+ break;
+ }
+ return (info && !info->IsDeleted()) ? info : NULL;
+ }
+
// Validates the program and location for a glGetUniform call and returns
// a SizeResult setup to receive the result. Returns true if glGetUniform
// should be called.
@@ -1219,8 +1252,9 @@ class GLES2DecoderImpl : public base::SupportsWeakPtr<GLES2DecoderImpl>,
// The program in use by glUseProgram
ProgramManager::ProgramInfo::Ref current_program_;
- // The currently bound framebuffer
- FramebufferManager::FramebufferInfo::Ref bound_framebuffer_;
+ // The currently bound framebuffers
+ FramebufferManager::FramebufferInfo::Ref bound_read_framebuffer_;
+ FramebufferManager::FramebufferInfo::Ref bound_draw_framebuffer_;
// The currently bound renderbuffer
RenderbufferManager::RenderbufferInfo::Ref bound_renderbuffer_;
@@ -1279,15 +1313,7 @@ ScopedTexture2DBinder::ScopedTexture2DBinder(GLES2DecoderImpl* decoder,
ScopedTexture2DBinder::~ScopedTexture2DBinder() {
ScopedGLErrorSuppressor suppressor(decoder_);
- GLES2DecoderImpl::TextureUnit& info = decoder_->texture_units_[0];
- GLuint last_id;
- if (info.bound_texture_2d)
- last_id = info.bound_texture_2d->service_id();
- else
- last_id = 0;
-
- glBindTexture(GL_TEXTURE_2D, last_id);
- glActiveTexture(GL_TEXTURE0 + decoder_->active_texture_unit_);
+ decoder_->RestoreCurrentTexture2DBindings();
}
ScopedRenderBufferBinder::ScopedRenderBufferBinder(GLES2DecoderImpl* decoder,
@@ -1299,10 +1325,7 @@ ScopedRenderBufferBinder::ScopedRenderBufferBinder(GLES2DecoderImpl* decoder,
ScopedRenderBufferBinder::~ScopedRenderBufferBinder() {
ScopedGLErrorSuppressor suppressor(decoder_);
- glBindRenderbufferEXT(
- GL_RENDERBUFFER,
- decoder_->bound_renderbuffer_ ?
- decoder_->bound_renderbuffer_->service_id() : 0);
+ decoder_->RestoreCurrentRenderbufferBindings();
}
ScopedFrameBufferBinder::ScopedFrameBufferBinder(GLES2DecoderImpl* decoder,
@@ -1314,16 +1337,7 @@ ScopedFrameBufferBinder::ScopedFrameBufferBinder(GLES2DecoderImpl* decoder,
ScopedFrameBufferBinder::~ScopedFrameBufferBinder() {
ScopedGLErrorSuppressor suppressor(decoder_);
- FramebufferManager::FramebufferInfo* info =
- decoder_->bound_framebuffer_.get();
- GLuint framebuffer_id = info ? info->service_id() : 0;
- if (framebuffer_id == 0 &&
- decoder_->offscreen_target_frame_buffer_.get()) {
- glBindFramebufferEXT(GL_FRAMEBUFFER,
- decoder_->offscreen_target_frame_buffer_->id());
- } else {
- glBindFramebufferEXT(GL_FRAMEBUFFER, framebuffer_id);
- }
+ decoder_->RestoreCurrentFramebufferBindings();
}
ScopedDefaultGLContext::ScopedDefaultGLContext(GLES2DecoderImpl* decoder)
@@ -1828,16 +1842,67 @@ bool GLES2DecoderImpl::MakeCurrent() {
return context_.get() ? context_->MakeCurrent() : false;
}
-gfx::Size GLES2DecoderImpl::GetBoundFrameBufferSize() {
- if (bound_framebuffer_ != 0) {
+void GLES2DecoderImpl::RestoreCurrentRenderbufferBindings() {
+ glBindRenderbufferEXT(
+ GL_RENDERBUFFER,
+ bound_renderbuffer_ ? bound_renderbuffer_->service_id() : 0);
+}
+
+static void RebindCurrentFramebuffer(
+ GLenum target,
+ FramebufferManager::FramebufferInfo* info,
+ FrameBuffer* offscreen_frame_buffer) {
+ GLuint framebuffer_id = info ? info->service_id() : 0;
+ if (framebuffer_id == 0 && offscreen_frame_buffer) {
+ framebuffer_id = offscreen_frame_buffer->id();
+ }
+ glBindFramebufferEXT(target, framebuffer_id);
+}
+
+void GLES2DecoderImpl::RestoreCurrentFramebufferBindings() {
+ if (!group_->extension_flags().ext_framebuffer_multisample) {
+ RebindCurrentFramebuffer(
+ GL_FRAMEBUFFER,
+ bound_draw_framebuffer_.get(),
+ offscreen_target_frame_buffer_.get());
+ } else {
+ RebindCurrentFramebuffer(
+ GL_READ_FRAMEBUFFER_EXT,
+ bound_read_framebuffer_.get(),
+ offscreen_target_frame_buffer_.get());
+ RebindCurrentFramebuffer(
+ GL_DRAW_FRAMEBUFFER_EXT,
+ bound_draw_framebuffer_.get(),
+ offscreen_target_frame_buffer_.get());
+ }
+}
+
+void GLES2DecoderImpl::RestoreCurrentTexture2DBindings() {
+ GLES2DecoderImpl::TextureUnit& info = texture_units_[0];
+ GLuint last_id;
+ if (info.bound_texture_2d) {
+ last_id = info.bound_texture_2d->service_id();
+ } else {
+ last_id = 0;
+ }
+
+ glBindTexture(GL_TEXTURE_2D, last_id);
+ glActiveTexture(GL_TEXTURE0 + active_texture_unit_);
+}
+
+gfx::Size GLES2DecoderImpl::GetBoundReadFrameBufferSize() {
+ if (bound_read_framebuffer_ != 0) {
int width = 0;
int height = 0;
+ GLenum target = group_->extension_flags().ext_framebuffer_multisample ?
+ GL_READ_FRAMEBUFFER_EXT : GL_FRAMEBUFFER;
+
// Assume we have to have COLOR_ATTACHMENT0. Should we check for depth and
// stencil.
GLint fb_type = 0;
glGetFramebufferAttachmentParameterivEXT(
- GL_FRAMEBUFFER,
+ target,
GL_COLOR_ATTACHMENT0,
GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE,
&fb_type);
@@ -1846,7 +1911,7 @@ gfx::Size GLES2DecoderImpl::GetBoundFrameBufferSize() {
{
GLint renderbuffer_id = 0;
glGetFramebufferAttachmentParameterivEXT(
- GL_FRAMEBUFFER,
+ target,
GL_COLOR_ATTACHMENT0,
GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME,
&renderbuffer_id);
@@ -1866,7 +1931,7 @@ gfx::Size GLES2DecoderImpl::GetBoundFrameBufferSize() {
{
GLint texture_id = 0;
glGetFramebufferAttachmentParameterivEXT(
- GL_FRAMEBUFFER,
+ target,
GL_COLOR_ATTACHMENT0,
GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME,
&texture_id);
@@ -1879,12 +1944,12 @@ gfx::Size GLES2DecoderImpl::GetBoundFrameBufferSize() {
GLint level = 0;
GLint face = 0;
glGetFramebufferAttachmentParameterivEXT(
- GL_FRAMEBUFFER,
+ target,
GL_COLOR_ATTACHMENT0,
GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_LEVEL,
&level);
glGetFramebufferAttachmentParameterivEXT(
- GL_FRAMEBUFFER,
+ target,
GL_COLOR_ATTACHMENT0,
GL_FRAMEBUFFER_ATTACHMENT_TEXTURE_CUBE_MAP_FACE,
&face);
@@ -2262,7 +2327,13 @@ void GLES2DecoderImpl::DoBindFramebuffer(GLenum target, GLuint client_id) {
service_id = info->service_id();
}
}
- bound_framebuffer_ = info;
+
+ if (target == GL_FRAMEBUFFER || target == GL_DRAW_FRAMEBUFFER_EXT) {
+ bound_draw_framebuffer_ = info;
+ }
+ if (target == GL_FRAMEBUFFER || target == GL_READ_FRAMEBUFFER_EXT) {
+ bound_read_framebuffer_ = info;
+ }
// When rendering to an offscreen frame buffer, instead of unbinding from
// the current frame buffer, bind to the offscreen target frame buffer.
@@ -2458,12 +2529,26 @@ bool GLES2DecoderImpl::GetHelper(
}
return true;
case GL_FRAMEBUFFER_BINDING:
+ // case GL_DRAW_FRAMEBUFFER_BINDING_EXT: (same as GL_FRAMEBUFFER_BINDING)
+ *num_written = 1;
+ if (params) {
+ if (bound_draw_framebuffer_) {
+ GLuint client_id = 0;
+ framebuffer_manager()->GetClientId(
+ bound_draw_framebuffer_->service_id(), &client_id);
+ *params = client_id;
+ } else {
+ *params = 0;
+ }
+ }
+ return true;
+ case GL_READ_FRAMEBUFFER_BINDING:
*num_written = 1;
if (params) {
- if (bound_framebuffer_) {
+ if (bound_read_framebuffer_) {
GLuint client_id = 0;
framebuffer_manager()->GetClientId(
- bound_framebuffer_->service_id(), &client_id);
+ bound_read_framebuffer_->service_id(), &client_id);
*params = client_id;
} else {
*params = 0;
@@ -2802,7 +2887,9 @@ void GLES2DecoderImpl::DoDrawArrays(
void GLES2DecoderImpl::DoFramebufferRenderbuffer(
GLenum target, GLenum attachment, GLenum renderbuffertarget,
GLuint client_renderbuffer_id) {
- if (!bound_framebuffer_) {
+ FramebufferManager::FramebufferInfo* framebuffer_info =
+ GetFramebufferInfoForTarget(target);
+ if (!framebuffer_info) {
SetGLError(GL_INVALID_OPERATION,
"glFramebufferRenderbuffer: no framebuffer bound");
return;
@@ -2822,9 +2909,9 @@ void GLES2DecoderImpl::DoFramebufferRenderbuffer(
target, attachment, renderbuffertarget, service_id);
if (service_id == 0 ||
glCheckFramebufferStatusEXT(target) == GL_FRAMEBUFFER_COMPLETE) {
- bound_framebuffer_->AttachRenderbuffer(attachment, info);
+ framebuffer_info->AttachRenderbuffer(attachment, info);
if (info) {
- ClearUnclearedRenderbuffers(bound_framebuffer_);
+ ClearUnclearedRenderbuffers(target, framebuffer_info);
}
}
}
@@ -2901,7 +2988,10 @@ void GLES2DecoderImpl::DoStencilMaskSeparate(GLenum face, GLuint mask) {
// are cleared because they are textures so we only need to clear
// the renderbuffers.
void GLES2DecoderImpl::ClearUnclearedRenderbuffers(
- FramebufferManager::FramebufferInfo* info) {
+ GLenum target, FramebufferManager::FramebufferInfo* info) {
+ if (target == GL_READ_FRAMEBUFFER_EXT) {
+ // TODO(gman): bind this to the DRAW point, clear then bind back to READ
+ }
GLbitfield clear_bits = 0;
if (info->HasUnclearedAttachment(GL_COLOR_ATTACHMENT0)) {
glClearColor(0, 0, 0, 0);
@@ -2939,10 +3029,16 @@ void GLES2DecoderImpl::ClearUnclearedRenderbuffers(
if (enable_scissor_test_) {
glEnable(GL_SCISSOR_TEST);
}
+
+ if (target == GL_READ_FRAMEBUFFER_EXT) {
+ // TODO(gman): rebind draw.
+ }
}
GLenum GLES2DecoderImpl::DoCheckFramebufferStatus(GLenum target) {
- if (!bound_framebuffer_) {
+ FramebufferManager::FramebufferInfo* info =
+ GetFramebufferInfoForTarget(target);
+ if (!info) {
return GL_FRAMEBUFFER_COMPLETE;
}
return glCheckFramebufferStatusEXT(target);
@@ -2951,7 +3047,9 @@ GLenum GLES2DecoderImpl::DoCheckFramebufferStatus(GLenum target) {
void GLES2DecoderImpl::DoFramebufferTexture2D(
GLenum target, GLenum attachment, GLenum textarget,
GLuint client_texture_id, GLint level) {
- if (!bound_framebuffer_) {
+ FramebufferManager::FramebufferInfo* framebuffer_info =
+ GetFramebufferInfoForTarget(target);
+ if (!framebuffer_info) {
SetGLError(GL_INVALID_OPERATION,
"glFramebufferTexture2D: no framebuffer bound.");
return;
@@ -2970,13 +3068,15 @@ void GLES2DecoderImpl::DoFramebufferTexture2D(
glFramebufferTexture2DEXT(target, attachment, textarget, service_id, level);
if (service_id != 0 &&
glCheckFramebufferStatusEXT(target) == GL_FRAMEBUFFER_COMPLETE) {
- ClearUnclearedRenderbuffers(bound_framebuffer_);
+ ClearUnclearedRenderbuffers(target, framebuffer_info);
}
}
void GLES2DecoderImpl::DoGetFramebufferAttachmentParameteriv(
GLenum target, GLenum attachment, GLenum pname, GLint* params) {
- if (!bound_framebuffer_) {
+ FramebufferManager::FramebufferInfo* framebuffer_info =
+ GetFramebufferInfoForTarget(target);
+ if (!framebuffer_info) {
SetGLError(GL_INVALID_OPERATION,
"glFramebufferAttachmentParameteriv: no framebuffer bound");
return;
@@ -3017,6 +3117,48 @@ void GLES2DecoderImpl::DoGetRenderbufferParameteriv(
glGetRenderbufferParameterivEXT(target, pname, params);
}
+void GLES2DecoderImpl::DoBlitFramebufferEXT(
+ GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
+ GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
+ GLbitfield mask, GLenum filter) {
+ if (!group_->extension_flags().ext_framebuffer_multisample) {
+ SetGLError(GL_INVALID_OPERATION,
+ "glBlitFramebufferEXT: function not available");
+ }
+ glBlitFramebufferEXT(
+ srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter);
+}
+
+void GLES2DecoderImpl::DoRenderbufferStorageMultisample(
+ GLenum target, GLsizei samples, GLenum internalformat,
+ GLsizei width, GLsizei height) {
+ if (!group_->extension_flags().ext_framebuffer_multisample) {
+ SetGLError(GL_INVALID_OPERATION,
+ "glRenderbufferStorageMultisampleEXT: function not available");
+ return;
+ }
+ bound_renderbuffer_->set_internal_format(internalformat);
+
+ if (gfx::GetGLImplementation() != gfx::kGLImplementationEGLGLES2) {
+ switch (internalformat) {
+ case GL_DEPTH_COMPONENT16:
+ internalformat = GL_DEPTH_COMPONENT;
+ break;
+ case GL_RGBA4:
+ case GL_RGB5_A1:
+ internalformat = GL_RGBA;
+ break;
+ case GL_RGB565:
+ internalformat = GL_RGB;
+ break;
+ }
+ }
+
+ glRenderbufferStorageMultisampleEXT(
+ target, samples, internalformat, width, height);
+ // TODO(gman) should not set internal format unless this succeeds
+}
+
void GLES2DecoderImpl::DoRenderbufferStorage(
GLenum target, GLenum internalformat, GLsizei width, GLsizei height) {
if (!bound_renderbuffer_) {
@@ -3042,6 +3184,7 @@ void GLES2DecoderImpl::DoRenderbufferStorage(
}
glRenderbufferStorageEXT(target, internalformat, width, height);
+ // TODO(gman) should not set internal format unless this succeeds
}
void GLES2DecoderImpl::DoLinkProgram(GLuint program) {
@@ -4087,7 +4230,7 @@ error::Error GLES2DecoderImpl::HandleReadPixels(
CopyRealGLErrorsToWrapper();
// Get the size of the current fbo or backbuffer.
- gfx::Size max_size = GetBoundFrameBufferSize();
+ gfx::Size max_size = GetBoundReadFrameBufferSize();
GLint max_x;
GLint max_y;
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder_autogen.h b/gpu/command_buffer/service/gles2_cmd_decoder_autogen.h
index 0ae6355..aefe831 100644
--- a/gpu/command_buffer/service/gles2_cmd_decoder_autogen.h
+++ b/gpu/command_buffer/service/gles2_cmd_decoder_autogen.h
@@ -2723,6 +2723,68 @@ error::Error GLES2DecoderImpl::HandleViewport(
return error::kNoError;
}
+error::Error GLES2DecoderImpl::HandleBlitFramebufferEXT(
+ uint32 immediate_data_size, const gles2::BlitFramebufferEXT& c) {
+ GLint srcX0 = static_cast<GLint>(c.srcX0);
+ GLint srcY0 = static_cast<GLint>(c.srcY0);
+ GLint srcX1 = static_cast<GLint>(c.srcX1);
+ GLint srcY1 = static_cast<GLint>(c.srcY1);
+ GLint dstX0 = static_cast<GLint>(c.dstX0);
+ GLint dstY0 = static_cast<GLint>(c.dstY0);
+ GLint dstX1 = static_cast<GLint>(c.dstX1);
+ GLint dstY1 = static_cast<GLint>(c.dstY1);
+ GLbitfield mask = static_cast<GLbitfield>(c.mask);
+ GLenum filter = static_cast<GLenum>(c.filter);
+ if (!validators_->blit_filter.IsValid(filter)) {
+ SetGLError(
+ GL_INVALID_ENUM, "glBlitFramebufferEXT: filter GL_INVALID_ENUM");
+ return error::kNoError;
+ }
+ DoBlitFramebufferEXT(
+ srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter);
+ return error::kNoError;
+}
+
+error::Error GLES2DecoderImpl::HandleRenderbufferStorageMultisampleEXT(
+ uint32 immediate_data_size,
+ const gles2::RenderbufferStorageMultisampleEXT& c) {
+ GLenum target = static_cast<GLenum>(c.target);
+ GLsizei samples = static_cast<GLsizei>(c.samples);
+ GLenum internalformat = static_cast<GLenum>(c.internalformat);
+ GLsizei width = static_cast<GLsizei>(c.width);
+ GLsizei height = static_cast<GLsizei>(c.height);
+ if (!validators_->render_buffer_target.IsValid(target)) {
+ SetGLError(
+ GL_INVALID_ENUM,
+ "glRenderbufferStorageMultisampleEXT: target GL_INVALID_ENUM");
+ return error::kNoError;
+ }
+ if (samples < 0) {
+ SetGLError(
+ GL_INVALID_VALUE, "glRenderbufferStorageMultisampleEXT: samples < 0");
+ return error::kNoError;
+ }
+ if (!validators_->render_buffer_format.IsValid(internalformat)) {
+ SetGLError(
+ GL_INVALID_ENUM,
+ "glRenderbufferStorageMultisampleEXT: internalformat GL_INVALID_ENUM");
+ return error::kNoError;
+ }
+ if (width < 0) {
+ SetGLError(
+ GL_INVALID_VALUE, "glRenderbufferStorageMultisampleEXT: width < 0");
+ return error::kNoError;
+ }
+ if (height < 0) {
+ SetGLError(
+ GL_INVALID_VALUE, "glRenderbufferStorageMultisampleEXT: height < 0");
+ return error::kNoError;
+ }
+ DoRenderbufferStorageMultisample(
+ target, samples, internalformat, width, height);
+ return error::kNoError;
+}
+
error::Error GLES2DecoderImpl::HandleGetMaxValueInBuffer(
uint32 immediate_data_size, const gles2::GetMaxValueInBuffer& c) {
GLuint buffer_id = c.buffer_id;
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder_unittest_1_autogen.h b/gpu/command_buffer/service/gles2_cmd_decoder_unittest_1_autogen.h
index 00fee19..4c7257e 100644
--- a/gpu/command_buffer/service/gles2_cmd_decoder_unittest_1_autogen.h
+++ b/gpu/command_buffer/service/gles2_cmd_decoder_unittest_1_autogen.h
@@ -79,7 +79,7 @@ TEST_F(GLES2DecoderTest1, BindFramebufferInvalidArgs0_0) {
EXPECT_CALL(*gl_, BindFramebufferEXT(_, _)).Times(0);
SpecializedSetup<BindFramebuffer, 0>(false);
BindFramebuffer cmd;
- cmd.Init(GL_RENDERBUFFER, client_framebuffer_id_);
+ cmd.Init(GL_READ_FRAMEBUFFER, client_framebuffer_id_);
EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
EXPECT_EQ(GL_INVALID_ENUM, GetGLError());
}
@@ -274,7 +274,7 @@ TEST_F(GLES2DecoderTest1, CheckFramebufferStatusInvalidArgs0_0) {
EXPECT_CALL(*gl_, CheckFramebufferStatusEXT(_)).Times(0);
SpecializedSetup<CheckFramebufferStatus, 0>(false);
CheckFramebufferStatus cmd;
- cmd.Init(GL_RENDERBUFFER, shared_memory_id_, shared_memory_offset_);
+ cmd.Init(GL_READ_FRAMEBUFFER, shared_memory_id_, shared_memory_offset_);
EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
EXPECT_EQ(GL_INVALID_ENUM, GetGLError());
}
@@ -780,7 +780,7 @@ TEST_F(GLES2DecoderTest1, FramebufferRenderbufferInvalidArgs0_0) {
SpecializedSetup<FramebufferRenderbuffer, 0>(false);
FramebufferRenderbuffer cmd;
cmd.Init(
- GL_RENDERBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER,
+ GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER,
client_renderbuffer_id_);
EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
EXPECT_EQ(GL_INVALID_ENUM, GetGLError());
@@ -816,8 +816,8 @@ TEST_F(GLES2DecoderTest1, FramebufferTexture2DInvalidArgs0_0) {
SpecializedSetup<FramebufferTexture2D, 0>(false);
FramebufferTexture2D cmd;
cmd.Init(
- GL_RENDERBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, client_texture_id_,
- 5);
+ GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D,
+ client_texture_id_, 5);
EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
EXPECT_EQ(GL_INVALID_ENUM, GetGLError());
}
@@ -1300,7 +1300,7 @@ TEST_F(GLES2DecoderTest1, GetFramebufferAttachmentParameterivInvalidArgs0_0) {
result->size = 0;
GetFramebufferAttachmentParameteriv cmd;
cmd.Init(
- GL_RENDERBUFFER, GL_COLOR_ATTACHMENT0,
+ GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE, shared_memory_id_,
shared_memory_offset_);
EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
@@ -1751,5 +1751,7 @@ TEST_F(GLES2DecoderTest1, GetTexParameterivInvalidArgs2_1) {
// TODO(gman): GetUniformLocation
+// TODO(gman): GetUniformLocationImmediate
+
#endif // GPU_COMMAND_BUFFER_SERVICE_GLES2_CMD_DECODER_UNITTEST_1_AUTOGEN_H_
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder_unittest_2_autogen.h b/gpu/command_buffer/service/gles2_cmd_decoder_unittest_2_autogen.h
index 9d8cc0a..0b6aee3 100644
--- a/gpu/command_buffer/service/gles2_cmd_decoder_unittest_2_autogen.h
+++ b/gpu/command_buffer/service/gles2_cmd_decoder_unittest_2_autogen.h
@@ -8,8 +8,6 @@
#ifndef GPU_COMMAND_BUFFER_SERVICE_GLES2_CMD_DECODER_UNITTEST_2_AUTOGEN_H_
#define GPU_COMMAND_BUFFER_SERVICE_GLES2_CMD_DECODER_UNITTEST_2_AUTOGEN_H_
-// TODO(gman): GetUniformLocationImmediate
-
// TODO(gman): GetUniformLocationBucket
@@ -1601,6 +1599,8 @@ TEST_F(GLES2DecoderTest2, ViewportInvalidArgs3_0) {
EXPECT_EQ(error::kNoError, ExecuteCmd(cmd));
EXPECT_EQ(GL_INVALID_VALUE, GetGLError());
}
+// TODO(gman): BlitFramebufferEXT
+// TODO(gman): RenderbufferStorageMultisampleEXT
// TODO(gman): SwapBuffers
// TODO(gman): GetMaxValueInBuffer
// TODO(gman): GenSharedIds
diff --git a/gpu/command_buffer/service/gles2_cmd_validation_autogen.h b/gpu/command_buffer/service/gles2_cmd_validation_autogen.h
index f6500fd..455d593 100644
--- a/gpu/command_buffer/service/gles2_cmd_validation_autogen.h
+++ b/gpu/command_buffer/service/gles2_cmd_validation_autogen.h
@@ -8,6 +8,7 @@
#define GPU_COMMAND_BUFFER_SERVICE_GLES2_CMD_VALIDATION_AUTOGEN_H_
ValueValidator<GLenum> attachment;
+ValueValidator<GLenum> blit_filter;
ValueValidator<GLenum> buffer_parameter;
ValueValidator<GLenum> buffer_target;
ValueValidator<GLenum> buffer_usage;
diff --git a/gpu/command_buffer/service/gles2_cmd_validation_implementation_autogen.h b/gpu/command_buffer/service/gles2_cmd_validation_implementation_autogen.h
index 3b2407a..fda2b8b 100644
--- a/gpu/command_buffer/service/gles2_cmd_validation_implementation_autogen.h
+++ b/gpu/command_buffer/service/gles2_cmd_validation_implementation_autogen.h
@@ -13,6 +13,11 @@ static GLenum valid_attachment_table[] = {
GL_STENCIL_ATTACHMENT,
};
+static GLenum valid_blit_filter_table[] = {
+ GL_NEAREST,
+ GL_LINEAR,
+};
+
static GLenum valid_buffer_parameter_table[] = {
GL_BUFFER_SIZE,
GL_BUFFER_USAGE,
@@ -413,6 +418,8 @@ static GLenum valid_vertex_pointer_table[] = {
Validators::Validators()
: attachment(
valid_attachment_table, arraysize(valid_attachment_table)),
+ blit_filter(
+ valid_blit_filter_table, arraysize(valid_blit_filter_table)),
buffer_parameter(
valid_buffer_parameter_table, arraysize(
valid_buffer_parameter_table)),