Index: gpu/command_buffer/service/gles2_cmd_decoder.cc |
=================================================================== |
--- gpu/command_buffer/service/gles2_cmd_decoder.cc (revision 132190) |
+++ 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); |
@@ -1166,7 +1176,7 @@ |
// simulated. |
bool SimulateAttrib0( |
GLuint max_vertex_accessed, bool* simulated); |
- void RestoreStateForSimulatedAttrib0(); |
+ void RestoreStateForAttrib(GLuint attrib); |
// Returns true if textures were set. |
bool SetBlackTextureForNonRenderableTextures(); |
@@ -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; |
@@ -4998,9 +5054,9 @@ |
return true; |
} |
-void GLES2DecoderImpl::RestoreStateForSimulatedAttrib0() { |
+void GLES2DecoderImpl::RestoreStateForAttrib(GLuint attrib) { |
const VertexAttribManager::VertexAttribInfo* info = |
- vertex_attrib_manager_->GetVertexAttribInfo(0); |
+ vertex_attrib_manager_->GetVertexAttribInfo(attrib); |
const void* ptr = reinterpret_cast<const void*>(info->offset()); |
BufferManager::BufferInfo* buffer_info = info->buffer(); |
glBindBuffer(GL_ARRAY_BUFFER, buffer_info ? buffer_info->service_id() : 0); |
@@ -5011,6 +5067,12 @@ |
glVertexAttribDivisorANGLE(0, info->divisor()); |
glBindBuffer(GL_ARRAY_BUFFER, |
bound_array_buffer_ ? bound_array_buffer_->service_id() : 0); |
+ |
+ if (info->enabled()) { |
+ glEnableVertexAttribArray(attrib); |
+ } else { |
+ glDisableVertexAttribArray(attrib); |
+ } |
} |
bool GLES2DecoderImpl::SimulateFixedAttribs( |
@@ -5183,7 +5245,7 @@ |
} |
} |
if (simulated_attrib_0) { |
- RestoreStateForSimulatedAttrib0(); |
+ RestoreStateForAttrib(0); |
} |
if (WasContextLost()) { |
LOG(ERROR) << " GLES2DecoderImpl: Context lost during DrawArrays."; |
@@ -5294,7 +5356,7 @@ |
} |
} |
if (simulated_attrib_0) { |
- RestoreStateForSimulatedAttrib0(); |
+ RestoreStateForAttrib(0); |
} |
if (WasContextLost()) { |
LOG(ERROR) << " GLES2DecoderImpl: Context lost during DrawElements."; |
@@ -5934,6 +5996,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 +6203,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 +8293,72 @@ |
} |
} |
+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); |
greggman
2012/04/18 01:04:30
Hi Jeff, continued from the email
This code needs
Jeff Timanus
2012/04/18 14:59:08
Done.
|
+ 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); |
greggman
2012/04/17 04:58:06
See comments in other places about the problems wi
Jeff Timanus
2012/04/18 14:59:08
Done.
|
+ } |
+ |
+ 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(); |
+ RestoreStateForAttrib( |
+ CopyTextureCHROMIUMResourceManager::kVertexPositionAttrib); |
+ RestoreStateForAttrib( |
+ CopyTextureCHROMIUMResourceManager::kVertexTextureAttrib); |
+ |
+ ApplyDirtyState(); |
+} |
+ |
static GLenum ExtractTypeFromStorageFormat(GLenum internalformat) { |
switch (internalformat) { |
case GL_RGB565: |