Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(159)

Unified Diff: gpu/command_buffer/service/vertex_attrib_manager.cc

Issue 12494005: Use client side arrays for GL_STREAM_DRAW attributes (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 7 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: gpu/command_buffer/service/vertex_attrib_manager.cc
diff --git a/gpu/command_buffer/service/vertex_attrib_manager.cc b/gpu/command_buffer/service/vertex_attrib_manager.cc
index 50c2dec6b02b5e949dd0ca15d8dfcfe4ecfb595a..fe346ab04be09471b3c219c07fc90898002322bf 100644
--- a/gpu/command_buffer/service/vertex_attrib_manager.cc
+++ b/gpu/command_buffer/service/vertex_attrib_manager.cc
@@ -9,13 +9,17 @@
#include "base/command_line.h"
#include "base/logging.h"
#include "base/memory/scoped_ptr.h"
+#include "base/string_number_conversions.h"
#include "build/build_config.h"
#define GLES2_GPU_SERVICE 1
#include "gpu/command_buffer/common/gles2_cmd_format.h"
#include "gpu/command_buffer/common/gles2_cmd_utils.h"
#include "gpu/command_buffer/service/buffer_manager.h"
+#include "gpu/command_buffer/service/feature_info.h"
#include "gpu/command_buffer/service/gl_utils.h"
+#include "gpu/command_buffer/service/gles2_cmd_decoder.h"
#include "gpu/command_buffer/service/gpu_switches.h"
+#include "gpu/command_buffer/service/program_manager.h"
#include "gpu/command_buffer/service/vertex_array_manager.h"
namespace gpu {
@@ -31,6 +35,7 @@ VertexAttrib::VertexAttrib()
gl_stride_(0),
real_stride_(16),
divisor_(0),
+ is_client_side_array_(false),
list_(NULL) {
}
@@ -154,5 +159,114 @@ void VertexAttribManager::Unbind(Buffer* buffer) {
}
}
+bool VertexAttribManager::ValidateBindings(
+ const char* function_name,
+ GLES2Decoder* decoder,
+ FeatureInfo* feature_info,
+ Program* current_program,
+ GLuint max_vertex_accessed,
+ GLsizei primcount) {
+ // true if any enabled, used divisor is zero
+ bool divisor0 = false;
+ const GLuint kInitialBufferId = 0xFFFFFFFFU;
+ GLuint current_buffer_id = kInitialBufferId;
+ bool use_client_side_arrays_for_stream_buffers = feature_info->workarounds(
+ ).use_client_side_arrays_for_stream_buffers;
+ // Validate all attribs currently enabled. If they are used by the current
+ // program then check that they have enough elements to handle the draw call.
+ // If they are not used by the current program check that they have a buffer
+ // assigned.
+ for (VertexAttribInfoList::iterator it = enabled_vertex_attribs_.begin();
+ it != enabled_vertex_attribs_.end(); ++it) {
+ VertexAttrib* attrib = *it;
+ const Program::VertexAttrib* attrib_info =
+ current_program->GetAttribInfoByLocation(attrib->index());
+ if (attrib_info) {
+ divisor0 |= (attrib->divisor() == 0);
+ GLuint count = attrib->MaxVertexAccessed(primcount, max_vertex_accessed);
+ // This attrib is used in the current program.
+ if (!attrib->CanAccess(count)) {
+ decoder->SetGLError(
+ GL_INVALID_OPERATION, function_name,
+ (std::string(
+ "attempt to access out of range vertices in attribute ") +
+ base::IntToString(attrib->index())).c_str());
+ return false;
+ }
+ if (use_client_side_arrays_for_stream_buffers) {
+ Buffer* buffer = attrib->buffer();
+ glEnableVertexAttribArray(attrib->index());
+ if (buffer->IsClientSideArray()) {
+ if (current_buffer_id != 0) {
+ current_buffer_id = 0;
+ glBindBuffer(GL_ARRAY_BUFFER, 0);
+ }
+ attrib->set_is_client_side_array(true);
+ const void* ptr = buffer->GetRange(attrib->offset(), 0);
+ DCHECK(ptr);
+ glVertexAttribPointer(
+ attrib->index(),
+ attrib->size(),
+ attrib->type(),
+ attrib->normalized(),
+ attrib->gl_stride(),
+ ptr);
+ } else if (attrib->is_client_side_array()) {
+ attrib->set_is_client_side_array(false);
+ GLuint new_buffer_id = buffer->service_id();
+ if (new_buffer_id != current_buffer_id) {
+ current_buffer_id = new_buffer_id;
+ glBindBuffer(GL_ARRAY_BUFFER, current_buffer_id);
+ }
+ const void* ptr = reinterpret_cast<const void*>(attrib->offset());
+ glVertexAttribPointer(
+ attrib->index(),
+ attrib->size(),
+ attrib->type(),
+ attrib->normalized(),
+ attrib->gl_stride(),
+ ptr);
+ }
+ }
+ } else {
+ // This attrib is not used in the current program.
+ if (!attrib->buffer()) {
+ decoder->SetGLError(
+ GL_INVALID_OPERATION, function_name,
+ (std::string(
+ "attempt to render with no buffer attached to "
+ "enabled attribute ") +
+ base::IntToString(attrib->index())).c_str());
+ return false;
+ } else if (use_client_side_arrays_for_stream_buffers) {
+ Buffer* buffer = attrib->buffer();
+ // Disable client side arrays for unused attributes else we'll
+ // read bad memory
+ if (buffer->IsClientSideArray()) {
+ // Don't disable attrib 0 since it's special.
+ if (attrib->index() > 0) {
+ glDisableVertexAttribArray(attrib->index());
+ }
+ }
+ }
+ }
+ }
+
+ if (primcount && !divisor0) {
+ decoder->SetGLError(
+ GL_INVALID_OPERATION, function_name,
+ "attempt instanced render with all attributes having "
+ "non-zero divisors");
+ return false;
+ }
+
+ if (current_buffer_id != kInitialBufferId) {
+ // Restore the buffer binding.
+ decoder->RestoreBufferBindings();
+ }
+
+ return true;
+}
+
} // namespace gles2
} // namespace gpu
« no previous file with comments | « gpu/command_buffer/service/vertex_attrib_manager.h ('k') | gpu/command_buffer/service/vertex_attrib_manager_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698