Index: gpu/command_buffer/service/gles2_cmd_decoder.cc |
=================================================================== |
--- gpu/command_buffer/service/gles2_cmd_decoder.cc (revision 132133) |
+++ gpu/command_buffer/service/gles2_cmd_decoder.cc (working copy) |
@@ -33,6 +33,7 @@ |
#include "gpu/command_buffer/service/feature_info.h" |
#include "gpu/command_buffer/service/framebuffer_manager.h" |
#include "gpu/command_buffer/service/gl_utils.h" |
+#include "gpu/command_buffer/service/gles2_cmd_copy_texture_chromium.h" |
#include "gpu/command_buffer/service/gles2_cmd_validation.h" |
#include "gpu/command_buffer/service/gpu_switches.h" |
#include "gpu/command_buffer/service/program_manager.h" |
@@ -726,6 +727,12 @@ |
GLuint io_surface_id, |
GLuint plane); |
+ void DoCopyTextureCHROMIUM( |
+ GLenum target, |
+ GLuint source_id, |
+ GLuint target_id, |
+ GLint level); |
+ |
// Wrapper for TexStorage2DEXT. |
void DoTexStorage2DEXT( |
GLenum target, |
@@ -1132,6 +1139,9 @@ |
void DoVertexAttrib3fv(GLuint index, const GLfloat *v); |
void DoVertexAttrib4fv(GLuint index, const GLfloat *v); |
+ // Wrapper for glViewport |
+ void DoViewport(GLint x, GLint y, GLsizei width, GLsizei height); |
+ |
// Wrapper for glUseProgram |
void DoUseProgram(GLuint program); |
@@ -1332,6 +1342,12 @@ |
// unpack alignment as last set by glPixelStorei |
GLint unpack_alignment_; |
+ // unpack flip y as last set by glPixelStorei |
+ bool unpack_flip_y_; |
+ |
+ // unpack premultiply alpha as last set by glPixelStorei |
+ bool unpack_premultiply_alpha_; |
+ |
// The currently bound array buffer. If this is 0 it is illegal to call |
// glVertexAttribPointer. |
BufferManager::BufferInfo::Ref bound_array_buffer_; |
@@ -1384,6 +1400,7 @@ |
GLuint mask_stencil_back_; |
GLclampf clear_depth_; |
GLboolean mask_depth_; |
+ bool enable_cull_face_; |
bool enable_scissor_test_; |
bool enable_depth_test_; |
bool enable_stencil_test_; |
@@ -1487,6 +1504,13 @@ |
typedef std::vector<GLES2DecoderImpl*> ChildList; |
ChildList children_; |
+ scoped_ptr<CopyTextureCHROMIUMResourceManager> copy_texture_CHROMIUM_; |
+ |
+ // Cached values of the currently assigned viewport dimensions. |
+ GLint viewport_x_, viewport_y_; |
+ GLsizei viewport_width_, viewport_height_; |
+ GLsizei viewport_max_width_, viewport_max_height_; |
+ |
DISALLOW_COPY_AND_ASSIGN(GLES2DecoderImpl); |
}; |
@@ -1830,6 +1854,8 @@ |
error_bits_(0), |
pack_alignment_(4), |
unpack_alignment_(4), |
+ unpack_flip_y_(false), |
+ unpack_premultiply_alpha_(false), |
attrib_0_buffer_id_(0), |
attrib_0_buffer_matches_value_(true), |
attrib_0_size_(0), |
@@ -1849,6 +1875,7 @@ |
mask_stencil_back_(-1), |
clear_depth_(1.0f), |
mask_depth_(true), |
+ enable_cull_face_(false), |
enable_scissor_test_(false), |
enable_depth_test_(false), |
enable_stencil_test_(false), |
@@ -1877,7 +1904,13 @@ |
needs_glsl_built_in_function_emulation_(false), |
force_webgl_glsl_validation_(false), |
derivatives_explicitly_enabled_(false), |
- compile_shader_always_succeeds_(false) { |
+ compile_shader_always_succeeds_(false), |
+ viewport_x_(0), |
+ viewport_y_(0), |
+ viewport_width_(0), |
+ viewport_height_(0), |
+ viewport_max_width_(0), |
+ viewport_max_height_(0) { |
DCHECK(group); |
attrib_0_value_.v[0] = 0.0f; |
@@ -1959,8 +1992,12 @@ |
Destroy(); |
return false; |
} |
+ CHECK_GL_ERROR(); |
+ copy_texture_CHROMIUM_.reset(new CopyTextureCHROMIUMResourceManager()); |
+ copy_texture_CHROMIUM_->Initialize(); |
CHECK_GL_ERROR(); |
+ |
disallowed_features_ = disallowed_features; |
vertex_attrib_manager_.reset(new VertexAttribManager()); |
@@ -2180,6 +2217,17 @@ |
return false; |
} |
+ GLint viewport_params[4]; |
+ glGetIntegerv(GL_VIEWPORT, viewport_params); |
+ viewport_x_ = viewport_params[0]; |
+ viewport_y_ = viewport_params[1]; |
+ viewport_width_ = viewport_params[2]; |
+ viewport_height_ = viewport_params[3]; |
+ |
+ glGetIntegerv(GL_MAX_VIEWPORT_DIMS, viewport_params); |
+ viewport_max_width_ = viewport_params[0]; |
+ viewport_max_height_ = viewport_params[0]; |
+ |
return true; |
} |
@@ -2686,6 +2734,8 @@ |
bound_renderbuffer_ = NULL; |
if (have_context) { |
+ copy_texture_CHROMIUM_->Destroy(); |
+ |
if (current_program_) { |
program_manager()->UnuseProgram(shader_manager(), current_program_); |
current_program_ = NULL; |
@@ -2736,6 +2786,7 @@ |
if (offscreen_resolved_color_texture_.get()) |
offscreen_resolved_color_texture_->Invalidate(); |
} |
+ copy_texture_CHROMIUM_.reset(); |
if (query_manager_.get()) { |
query_manager_->Destroy(have_context); |
@@ -3200,6 +3251,8 @@ |
glStencilMaskSeparate(GL_FRONT, have_stencil ? mask_stencil_front_ : 0); |
glStencilMaskSeparate(GL_BACK, have_stencil ? mask_stencil_back_ : 0); |
EnableDisable(GL_STENCIL_TEST, enable_stencil_test_ && have_stencil); |
+ EnableDisable(GL_CULL_FACE, enable_cull_face_); |
+ EnableDisable(GL_SCISSOR_TEST, enable_scissor_test_); |
state_dirty_ = false; |
} |
} |
@@ -4010,6 +4063,9 @@ |
bool GLES2DecoderImpl::SetCapabilityState(GLenum cap, bool enabled) { |
switch (cap) { |
+ case GL_CULL_FACE: |
+ enable_cull_face_ = enabled; |
+ return true; |
case GL_SCISSOR_TEST: |
enable_scissor_test_ = enabled; |
return true; |
@@ -5934,6 +5990,15 @@ |
return error::kNoError; |
} |
+void GLES2DecoderImpl::DoViewport(GLint x, GLint y, GLsizei width, |
+ GLsizei height) { |
+ viewport_x_ = x; |
+ viewport_y_ = y; |
+ viewport_width_ = std::min(width, viewport_max_width_); |
+ viewport_height_ = std::min(height, viewport_max_height_); |
+ glViewport(x, y, width, height); |
+} |
+ |
error::Error GLES2DecoderImpl::HandleVertexAttribDivisorANGLE( |
uint32 immediate_data_size, const gles2::VertexAttribDivisorANGLE& c) { |
if (!feature_info_->feature_flags().angle_instanced_arrays) { |
@@ -6132,6 +6197,12 @@ |
case GL_UNPACK_ALIGNMENT: |
unpack_alignment_ = param; |
break; |
+ case GL_UNPACK_FLIP_Y_CHROMIUM: |
+ unpack_flip_y_ = (param != 0); |
+ break; |
+ case GL_UNPACK_PREMULTIPLY_ALPHA_CHROMIUM: |
+ unpack_premultiply_alpha_ = (param != 0); |
+ break; |
default: |
// Validation should have prevented us from getting here. |
NOTREACHED(); |
@@ -8216,6 +8287,73 @@ |
} |
} |
+void GLES2DecoderImpl::DoCopyTextureCHROMIUM( |
+ GLenum target, GLuint source_id, GLuint dest_id, GLint level) { |
+ TextureManager::TextureInfo* dest_info = GetTextureInfo(dest_id); |
+ TextureManager::TextureInfo* source_info = GetTextureInfo(source_id); |
+ |
+ if (!source_info || !dest_info) { |
+ SetGLError(GL_INVALID_VALUE, "glCopyTextureCHROMIUM: unknown texture id"); |
+ return; |
+ } |
+ |
+ if (GL_TEXTURE_2D != target) { |
+ SetGLError(GL_INVALID_VALUE, |
+ "glCopyTextureCHROMIUM: invalid texture target"); |
+ return; |
+ } |
+ |
+ int source_width, source_height, dest_width, dest_height; |
+ if (!source_info->GetLevelSize(GL_TEXTURE_2D, 0, &source_width, |
+ &source_height)) { |
+ SetGLError(GL_INVALID_VALUE, |
+ "glCopyTextureChromium: source texture has no level 0"); |
+ return; |
+ } |
+ |
+ if (!dest_info->GetLevelSize(GL_TEXTURE_2D, level, &dest_width, |
+ &dest_height)) { |
+ SetGLError(GL_INVALID_VALUE, |
+ "glCopyTextureChromium: destination texture level does not exist"); |
+ return; |
+ } |
+ |
+ // Resize the destination texture to the dimensions of the source texture. |
+ if (dest_width != source_width && dest_height != source_height) { |
+ GLenum type; |
+ GLenum internal_format; |
+ dest_info->GetLevelType(GL_TEXTURE_2D, level, &type, &internal_format); |
+ glTexImage2D(GL_TEXTURE_2D, level, internal_format, source_width, |
+ source_height, 0, internal_format, type, NULL); |
+ |
+ dest_info->SetLevelSize(GL_TEXTURE_2D, level, source_width, source_height); |
+ } |
+ |
+ state_dirty_ = true; |
+ glViewport(0, 0, dest_width, dest_height); |
+ copy_texture_CHROMIUM_->DoCopyTexture(target, source_info->service_id(), |
+ dest_info->service_id(), level, |
+ unpack_flip_y_, |
+ unpack_premultiply_alpha_); |
+ glViewport(viewport_x_, viewport_y_, viewport_width_, viewport_height_); |
+ |
+ // Restore all of the state touched by the extension. |
+ if (current_program_) |
+ glUseProgram(current_program_->service_id()); |
+ else |
+ glUseProgram(0); |
+ |
+ RestoreCurrentFramebufferBindings(); |
+ RestoreCurrentTexture2DBindings(); |
+ |
+ if (!bound_array_buffer_) |
greggman
2012/04/15 22:22:41
This isn't enough to restore the state changed in
Jeff Timanus
2012/04/17 01:27:34
I follow the need to restore the settings. I had
|
+ glBindBuffer(GL_ARRAY_BUFFER, 0); |
+ else |
+ glBindBuffer(GL_ARRAY_BUFFER, bound_array_buffer_->service_id()); |
+ |
+ ApplyDirtyState(); |
+} |
+ |
static GLenum ExtractTypeFromStorageFormat(GLenum internalformat) { |
switch (internalformat) { |
case GL_RGB565: |