summaryrefslogtreecommitdiffstats
path: root/gpu/command_buffer/service
diff options
context:
space:
mode:
Diffstat (limited to 'gpu/command_buffer/service')
-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
9 files changed, 318 insertions, 57 deletions
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)),