summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorbsalomon@google.com <bsalomon@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2011-11-30 18:06:39 +0000
committerbsalomon@google.com <bsalomon@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2011-11-30 18:06:39 +0000
commit222471da4b95342d222ad9ee32d0e33725c45fa8 (patch)
tree1f891053535431f2a06fa563daae446cccbaa826
parent2978339a797536e720a18ebdde2fd7f1b4e12c34 (diff)
downloadchromium_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.cc67
-rw-r--r--gpu/command_buffer/client/gles2_implementation.h15
-rw-r--r--gpu/command_buffer/common/gles2_cmd_utils.cc2
-rw-r--r--gpu/command_buffer/service/feature_info.cc8
-rw-r--r--gpu/command_buffer/service/feature_info.h2
-rw-r--r--gpu/command_buffer/service/gl_utils.h3
-rw-r--r--gpu/command_buffer/service/gles2_cmd_decoder.cc15
-rw-r--r--third_party/khronos/GLES2/gl2ext.h10
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
*------------------------------------------------------------------------*/