diff options
author | bsalomon@google.com <bsalomon@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-11-30 18:06:39 +0000 |
---|---|---|
committer | bsalomon@google.com <bsalomon@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-11-30 18:06:39 +0000 |
commit | 222471da4b95342d222ad9ee32d0e33725c45fa8 (patch) | |
tree | 1f891053535431f2a06fa563daae446cccbaa826 | |
parent | 2978339a797536e720a18ebdde2fd7f1b4e12c34 (diff) | |
download | chromium_src-222471da4b95342d222ad9ee32d0e33725c45fa8.zip chromium_src-222471da4b95342d222ad9ee32d0e33725c45fa8.tar.gz chromium_src-222471da4b95342d222ad9ee32d0e33725c45fa8.tar.bz2 |
Add GL_ANGLE_pack_reverse_row_order to command buffer
Bug=82559
Review URL: http://codereview.chromium.org/8513017
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@112245 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r-- | gpu/command_buffer/client/gles2_implementation.cc | 67 | ||||
-rw-r--r-- | gpu/command_buffer/client/gles2_implementation.h | 15 | ||||
-rw-r--r-- | gpu/command_buffer/common/gles2_cmd_utils.cc | 2 | ||||
-rw-r--r-- | gpu/command_buffer/service/feature_info.cc | 8 | ||||
-rw-r--r-- | gpu/command_buffer/service/feature_info.h | 2 | ||||
-rw-r--r-- | gpu/command_buffer/service/gl_utils.h | 3 | ||||
-rw-r--r-- | gpu/command_buffer/service/gles2_cmd_decoder.cc | 15 | ||||
-rw-r--r-- | third_party/khronos/GLES2/gl2ext.h | 10 |
8 files changed, 116 insertions, 6 deletions
diff --git a/gpu/command_buffer/client/gles2_implementation.cc b/gpu/command_buffer/client/gles2_implementation.cc index 99eac94..84fc9a7 100644 --- a/gpu/command_buffer/client/gles2_implementation.cc +++ b/gpu/command_buffer/client/gles2_implementation.cc @@ -540,9 +540,11 @@ GLES2Implementation::GLES2Implementation( helper, static_cast<char*>(transfer_buffer) + kStartingOffset), transfer_buffer_id_(transfer_buffer_id), + angle_pack_reverse_row_order_status(kUnknownExtensionStatus), pack_alignment_(4), unpack_alignment_(4), unpack_flip_y_(false), + pack_reverse_row_order_(false), active_texture_unit_(0), bound_framebuffer_(0), bound_renderbuffer_(0), @@ -648,6 +650,41 @@ void GLES2Implementation::WaitForCmd() { helper_->CommandBufferHelper::Finish(); } +namespace { +bool IsExtensionAvailable(GLES2Implementation* gles2, const char ext[]) { + const char* extensions = reinterpret_cast<const char*>( + gles2->GetString(GL_EXTENSIONS)); + int length = strlen(ext); + while (true) { + int n = strcspn(extensions, " "); + if (n == length && 0 == strncmp(ext, extensions, length)) { + return true; + } + if ('\0' == extensions[n]) { + return false; + } + extensions += n+1; + } +} +} + +bool GLES2Implementation::IsAnglePackReverseRowOrderAvailable() { + switch (angle_pack_reverse_row_order_status) { + case kAvailableExtensionStatus: + return true; + case kUnavailableExtensionStatus: + return false; + default: + if (IsExtensionAvailable(this, "GL_ANGLE_pack_reverse_row_order")) { + angle_pack_reverse_row_order_status = kAvailableExtensionStatus; + return true; + } else { + angle_pack_reverse_row_order_status = kUnavailableExtensionStatus; + return false; + } + } +} + GLenum GLES2Implementation::GetError() { GPU_CLIENT_LOG("[" << this << "] glGetError()"); GLenum err = GetGLError(); @@ -1221,6 +1258,10 @@ void GLES2Implementation::PixelStorei(GLenum pname, GLint param) { case GL_UNPACK_FLIP_Y_CHROMIUM: unpack_flip_y_ = (param != 0); return; + case GL_PACK_REVERSE_ROW_ORDER_ANGLE: + pack_reverse_row_order_ = + IsAnglePackReverseRowOrderAvailable() ? (param != 0) : false; + break; default: break; } @@ -1975,13 +2016,25 @@ void GLES2Implementation::ReadPixels( result_shm_id(), result_shm_offset()); WaitForCmd(); if (*result != 0) { + // when doing a y-flip we have to iterate through top-to-bottom chunks + // of the dst. The service side handles reversing the rows within a + // chunk. + int8* rows_dst; + if (pack_reverse_row_order_) { + rows_dst = dest + (height - num_rows) * padded_row_size; + } else { + rows_dst = dest; + } // We have to copy 1 row at a time to avoid writing pad bytes. const int8* src = static_cast<const int8*>(buffer); for (GLint yy = 0; yy < num_rows; ++yy) { - memcpy(dest, src, unpadded_row_size); - dest += padded_row_size; + memcpy(rows_dst, src, unpadded_row_size); + rows_dst += padded_row_size; src += padded_row_size; } + if (!pack_reverse_row_order_) { + dest = rows_dst; + } } transfer_buffer_.FreePendingToken(buffer, helper_->InsertToken()); // If it was not marked as successful exit. @@ -1998,6 +2051,10 @@ void GLES2Implementation::ReadPixels( GLsizeiptr element_size = temp_size; max_size -= max_size % element_size; GLint max_sub_row_pixels = max_size / element_size; + if (pack_reverse_row_order_) { + // start at the last row when flipping y. + dest = dest + (height - 1) * padded_row_size; + } for (; height; --height) { GLint temp_width = width; GLint temp_xoffset = xoffset; @@ -2025,7 +2082,7 @@ void GLES2Implementation::ReadPixels( temp_width -= num_pixels; } ++yoffset; - dest += padded_row_size; + dest += pack_reverse_row_order_ ? -padded_row_size : padded_row_size; } } } @@ -2520,6 +2577,10 @@ void GLES2Implementation::RequestExtensionCHROMIUM(const char* extension) { SetBucketAsCString(kResultBucketId, extension); helper_->RequestExtensionCHROMIUM(kResultBucketId); helper_->SetBucketSize(kResultBucketId, 0); + if (kUnavailableExtensionStatus == angle_pack_reverse_row_order_status && + !strcmp(extension, "GL_ANGLE_pack_reverse_row_order")) { + angle_pack_reverse_row_order_status = kUnknownExtensionStatus; + } } void GLES2Implementation::RateLimitOffscreenContextCHROMIUM() { diff --git a/gpu/command_buffer/client/gles2_implementation.h b/gpu/command_buffer/client/gles2_implementation.h index 407bd51..e085efc 100644 --- a/gpu/command_buffer/client/gles2_implementation.h +++ b/gpu/command_buffer/client/gles2_implementation.h @@ -202,6 +202,13 @@ class GLES2Implementation { void FreeUnusedSharedMemory(); private: + // Used to track whether an extension is available + enum ExtensionStatus { + kAvailableExtensionStatus, + kUnavailableExtensionStatus, + kUnknownExtensionStatus + }; + // Wraps RingBufferWrapper to provide aligned allocations. class AlignedRingBuffer : public RingBufferWrapper { public: @@ -338,6 +345,9 @@ class GLES2Implementation { return static_cast<T>(result_buffer_); } + // Lazily determines if GL_ANGLE_pack_reverse_row_order is available + bool IsAnglePackReverseRowOrderAvailable(); + // Gets the GLError through our wrapper. GLenum GetGLError(); @@ -432,6 +442,8 @@ class GLES2Implementation { std::queue<int32> swap_buffers_tokens_; std::queue<int32> rate_limit_tokens_; + ExtensionStatus angle_pack_reverse_row_order_status; + GLState gl_state_; // pack alignment as last set by glPixelStorei @@ -443,6 +455,9 @@ class GLES2Implementation { // unpack yflip as last set by glPixelstorei bool unpack_flip_y_; + // pack reverse row order as last set by glPixelstorei + bool pack_reverse_row_order_; + scoped_array<TextureUnit> texture_units_; // 0 to gl_state_.max_combined_texture_image_units. diff --git a/gpu/command_buffer/common/gles2_cmd_utils.cc b/gpu/command_buffer/common/gles2_cmd_utils.cc index 22763b6..b2be64b 100644 --- a/gpu/command_buffer/common/gles2_cmd_utils.cc +++ b/gpu/command_buffer/common/gles2_cmd_utils.cc @@ -127,6 +127,8 @@ int GLES2Util::GLGetNumValuesReturned(int id) const { return 1; case GL_PACK_ALIGNMENT: return 1; + case GL_PACK_REVERSE_ROW_ORDER_ANGLE: + return 1; case GL_POLYGON_OFFSET_FACTOR: return 1; case GL_POLYGON_OFFSET_FILL: diff --git a/gpu/command_buffer/service/feature_info.cc b/gpu/command_buffer/service/feature_info.cc index ea74412..c3cb1ee9 100644 --- a/gpu/command_buffer/service/feature_info.cc +++ b/gpu/command_buffer/service/feature_info.cc @@ -397,6 +397,14 @@ void FeatureInfo::AddFeatures(const char* desired_features) { if (ext.HaveAndDesire("GL_CHROMIUM_front_buffer_cached")) { AddExtensionString("GL_CHROMIUM_front_buffer_cached"); } + + if (ext.Desire("GL_ANGLE_pack_reverse_row_order") && + ext.Have("GL_ANGLE_pack_reverse_row_order")) { + AddExtensionString("GL_ANGLE_pack_reverse_row_order"); + feature_flags_.angle_pack_reverse_row_order = true; + validators_.pixel_store.AddValue(GL_PACK_REVERSE_ROW_ORDER_ANGLE); + validators_.g_l_state.AddValue(GL_PACK_REVERSE_ROW_ORDER_ANGLE); + } } void FeatureInfo::AddExtensionString(const std::string& str) { diff --git a/gpu/command_buffer/service/feature_info.h b/gpu/command_buffer/service/feature_info.h index fb4177b..c71ab9b 100644 --- a/gpu/command_buffer/service/feature_info.h +++ b/gpu/command_buffer/service/feature_info.h @@ -26,6 +26,7 @@ class FeatureInfo { chromium_webglsl(false), chromium_stream_texture(false), angle_translated_shader_source(false), + angle_pack_reverse_row_order(false), arb_texture_rectangle(false) { } @@ -38,6 +39,7 @@ class FeatureInfo { bool chromium_webglsl; bool chromium_stream_texture; bool angle_translated_shader_source; + bool angle_pack_reverse_row_order; bool arb_texture_rectangle; }; diff --git a/gpu/command_buffer/service/gl_utils.h b/gpu/command_buffer/service/gl_utils.h index 0aae91d..8371b5f 100644 --- a/gpu/command_buffer/service/gl_utils.h +++ b/gpu/command_buffer/service/gl_utils.h @@ -42,6 +42,9 @@ // GL_ANGLE_translated_shader_source #define GL_TRANSLATED_SHADER_SOURCE_LENGTH_ANGLE 0x93A0 +// GL_ANGLE_pack_reverse_row_order +#define GL_PACK_REVERSE_ROW_ORDER_ANGLE 0x93A4 + #define GL_GLEXT_PROTOTYPES 1 // Define this for extra GL error debugging (slower). diff --git a/gpu/command_buffer/service/gles2_cmd_decoder.cc b/gpu/command_buffer/service/gles2_cmd_decoder.cc index 6ba84f9..e2d60da 100644 --- a/gpu/command_buffer/service/gles2_cmd_decoder.cc +++ b/gpu/command_buffer/service/gles2_cmd_decoder.cc @@ -5801,15 +5801,24 @@ error::Error GLES2DecoderImpl::HandlePixelStorei( SetGLError(GL_INVALID_ENUM, "glPixelStorei: pname GL_INVALID_ENUM"); return error::kNoError; } - if (!validators_->pixel_store_alignment.IsValid(param)) { - SetGLError(GL_INVALID_VALUE, "glPixelSTore: param GL_INVALID_VALUE"); - return error::kNoError; + switch (pname) { + case GL_PACK_ALIGNMENT: + case GL_UNPACK_ALIGNMENT: + if (!validators_->pixel_store_alignment.IsValid(param)) { + SetGLError(GL_INVALID_VALUE, + "glPixelSTore: param GL_INVALID_VALUE"); + return error::kNoError; + } + default: + break; } glPixelStorei(pname, param); switch (pname) { case GL_PACK_ALIGNMENT: pack_alignment_ = param; break; + case GL_PACK_REVERSE_ROW_ORDER_ANGLE: + break; case GL_UNPACK_ALIGNMENT: unpack_alignment_ = param; break; diff --git a/third_party/khronos/GLES2/gl2ext.h b/third_party/khronos/GLES2/gl2ext.h index f1a49dc..fb105eb 100644 --- a/third_party/khronos/GLES2/gl2ext.h +++ b/third_party/khronos/GLES2/gl2ext.h @@ -207,6 +207,11 @@ typedef void* GLeglImageOES; #define GL_MAX_SAMPLES_ANGLE 0x8D57 #endif +/* GL_ANGLE_pack_reverse_row_order */ +#ifndef GL_ANGLE_pack_reverse_row_order +#define GL_PACK_REVERSE_ROW_ORDER_ANGLE 0x93A4 +#endif + /*------------------------------------------------------------------------* * APPLE extension tokens *------------------------------------------------------------------------*/ @@ -790,6 +795,11 @@ GL_APICALL void GL_APIENTRY glRenderbufferStorageMultisampleANGLE (GLenum target typedef void (GL_APIENTRYP PFNGLRENDERBUFFERSTORAGEMULTISAMPLEANGLEPROC) (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height); #endif +/* GL_ANGLE_pack_reverse_row_order */ +#ifndef GL_ANGLE_pack_reverse_row_order +#define GL_ANGLE_pack_reverse_row_order 1 +#endif + /*------------------------------------------------------------------------* * APPLE extension functions *------------------------------------------------------------------------*/ |