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

Unified Diff: gpu/command_buffer/client/gles2_implementation.cc

Issue 7633060: Add option to not generate resources on bind in OpenGL ES (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: nacl fix Created 9 years, 4 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/client/gles2_implementation.cc
diff --git a/gpu/command_buffer/client/gles2_implementation.cc b/gpu/command_buffer/client/gles2_implementation.cc
index fc4f547a4d4e2cc3193d1498ea5fa16e85f273b2..e34e47675e123bedb23ce98bf90132059dd87d6d 100644
--- a/gpu/command_buffer/client/gles2_implementation.cc
+++ b/gpu/command_buffer/client/gles2_implementation.cc
@@ -6,6 +6,8 @@
#include "../client/gles2_implementation.h"
+#include <set>
+#include <queue>
#include <GLES2/gl2ext.h>
#include "../client/mapped_memory.h"
#include "../client/program_info_manager.h"
@@ -51,10 +53,11 @@ class NonSharedIdHandler : public IdHandlerInterface {
}
// Overridden from IdHandlerInterface.
- virtual void FreeIds(GLsizei n, const GLuint* ids) {
+ virtual bool FreeIds(GLsizei n, const GLuint* ids) {
for (GLsizei ii = 0; ii < n; ++ii) {
id_allocator_.FreeID(ids[ii]);
}
+ return true;
}
// Overridden from IdHandlerInterface.
@@ -79,8 +82,9 @@ class NonSharedNonReusedIdHandler : public IdHandlerInterface {
}
// Overridden from IdHandlerInterface.
- virtual void FreeIds(GLsizei /* n */, const GLuint* /* ids */) {
+ virtual bool FreeIds(GLsizei /* n */, const GLuint* /* ids */) {
// Ids are never freed.
+ return true;
}
// Overridden from IdHandlerInterface.
@@ -109,20 +113,109 @@ class SharedIdHandler : public IdHandlerInterface {
gles2_->GenSharedIdsCHROMIUM(id_namespace_, id_offset, n, ids);
}
- virtual void FreeIds(GLsizei n, const GLuint* ids) {
+ virtual bool FreeIds(GLsizei n, const GLuint* ids) {
gles2_->DeleteSharedIdsCHROMIUM(id_namespace_, n, ids);
+ return true;
+ }
+
+ virtual bool MarkAsUsedForBind(GLuint /* id */) {
+ // This has no meaning for shared resources.
+ return true;
+ }
+
+ private:
+ GLES2Implementation* gles2_;
+ id_namespaces::IdNamespaces id_namespace_;
+};
+
+// An id handler for shared ids that requires ids are made before using and
+// that only the context that created the id can delete it.
+// Assumes the service will enforce that non made ids generate an error.
+class StrictSharedIdHandler : public IdHandlerInterface {
+ public:
+ StrictSharedIdHandler(
+ GLES2Implementation* gles2,
+ id_namespaces::IdNamespaces id_namespace)
+ : gles2_(gles2),
+ id_namespace_(id_namespace) {
+ }
+
+ virtual ~StrictSharedIdHandler() { }
+
+ virtual void MakeIds(GLuint id_offset, GLsizei n, GLuint* ids) {
+ for (GLsizei ii = 0; ii < n; ++ii) {
+ ids[ii] = GetId(id_offset);
+ }
}
- virtual bool MarkAsUsedForBind(GLuint) { // NOLINT
+ virtual bool FreeIds(GLsizei n, const GLuint* ids) {
+ // OpenGL sematics. If any id is bad none of them get freed.
+ for (GLsizei ii = 0; ii < n; ++ii) {
+ GLuint id = ids[ii];
+ if (id != 0) {
+ ResourceIdSet::iterator it = used_ids_.find(id);
+ if (it == used_ids_.end()) {
+ return false;
+ }
+ }
+ }
+ for (GLsizei ii = 0; ii < n; ++ii) {
+ GLuint id = ids[ii];
+ if (id != 0) {
+ ResourceIdSet::iterator it = used_ids_.find(id);
+ if (it != used_ids_.end()) {
+ used_ids_.erase(it);
+ free_ids_.push(id);
+ }
+ }
+ }
+ return true;
+ }
+
+ virtual bool MarkAsUsedForBind(GLuint /* id */) {
// This has no meaning for shared resources.
return true;
}
private:
+ static const GLsizei kNumIdsToGet = 2048;
+ typedef std::queue<GLuint> ResourceIdQueue;
+ typedef std::set<GLuint> ResourceIdSet;
+
+ GLuint GetId(GLuint id_offset) {
+ if (free_ids_.empty()) {
+ GLuint ids[kNumIdsToGet];
+ gles2_->GenSharedIdsCHROMIUM(id_namespace_, id_offset, kNumIdsToGet, ids);
+ for (GLsizei ii = 0; ii < kNumIdsToGet; ++ii) {
+ free_ids_.push(ids[ii]);
+ }
+ }
+ GLuint id = free_ids_.front();
+ free_ids_.pop();
+ used_ids_.insert(id);
+ return id;
+ }
+
+ bool FreeId(GLuint id) {
+ ResourceIdSet::iterator it = used_ids_.find(id);
+ if (it == used_ids_.end()) {
+ return false;
+ }
+ used_ids_.erase(it);
+ free_ids_.push(id);
+ return true;
+ }
+
GLES2Implementation* gles2_;
id_namespaces::IdNamespaces id_namespace_;
+ ResourceIdSet used_ids_;
+ ResourceIdQueue free_ids_;
};
+#ifndef _MSC_VER
+const GLsizei StrictSharedIdHandler::kNumIdsToGet;
+#endif
+
static GLsizei RoundUpToMultipleOf4(GLsizei size) {
return (size + 3) & ~3;
}
@@ -435,7 +528,8 @@ GLES2Implementation::GLES2Implementation(
size_t transfer_buffer_size,
void* transfer_buffer,
int32 transfer_buffer_id,
- bool share_resources)
+ bool share_resources,
+ bool bind_generates_resource)
: helper_(helper),
transfer_buffer_(
kStartingOffset,
@@ -455,7 +549,8 @@ GLES2Implementation::GLES2Implementation(
client_side_element_array_id_(0),
error_bits_(0),
debug_(false),
- sharing_resources_(share_resources) {
+ sharing_resources_(share_resources),
+ bind_generates_resource_(bind_generates_resource) {
GPU_CLIENT_LOG_CODE_BLOCK({
debug_ = CommandLine::ForCurrentProcess()->HasSwitch(
switches::kEnableGPUClientLogging);
@@ -469,16 +564,29 @@ GLES2Implementation::GLES2Implementation(
mapped_memory_.reset(new MappedMemoryManager(helper_));
if (share_resources) {
- buffer_id_handler_.reset(
- new SharedIdHandler(this, id_namespaces::kBuffers));
- framebuffer_id_handler_.reset(
- new SharedIdHandler(this, id_namespaces::kFramebuffers));
- renderbuffer_id_handler_.reset(
- new SharedIdHandler(this, id_namespaces::kRenderbuffers));
- program_and_shader_id_handler_.reset(
- new SharedIdHandler(this, id_namespaces::kProgramsAndShaders));
- texture_id_handler_.reset(
- new SharedIdHandler(this, id_namespaces::kTextures));
+ if (!bind_generates_resource) {
+ buffer_id_handler_.reset(
+ new StrictSharedIdHandler(this, id_namespaces::kBuffers));
+ framebuffer_id_handler_.reset(
+ new StrictSharedIdHandler(this, id_namespaces::kFramebuffers));
+ renderbuffer_id_handler_.reset(
+ new StrictSharedIdHandler(this, id_namespaces::kRenderbuffers));
+ program_and_shader_id_handler_.reset(
+ new StrictSharedIdHandler(this, id_namespaces::kProgramsAndShaders));
+ texture_id_handler_.reset(
+ new StrictSharedIdHandler(this, id_namespaces::kTextures));
+ } else {
+ buffer_id_handler_.reset(
+ new SharedIdHandler(this, id_namespaces::kBuffers));
+ framebuffer_id_handler_.reset(
+ new SharedIdHandler(this, id_namespaces::kFramebuffers));
+ renderbuffer_id_handler_.reset(
+ new SharedIdHandler(this, id_namespaces::kRenderbuffers));
+ program_and_shader_id_handler_.reset(
+ new SharedIdHandler(this, id_namespaces::kProgramsAndShaders));
+ texture_id_handler_.reset(
+ new SharedIdHandler(this, id_namespaces::kTextures));
+ }
} else {
buffer_id_handler_.reset(new NonSharedIdHandler());
framebuffer_id_handler_.reset(new NonSharedIdHandler());
@@ -514,7 +622,6 @@ GLES2Implementation::GLES2Implementation(
texture_units_.reset(
new TextureUnit[gl_state_.max_combined_texture_image_units]);
-
program_info_manager_.reset(ProgramInfoManager::Create(sharing_resources_));
#if defined(GLES2_SUPPORT_CLIENT_SIDE_ARRAYS)
@@ -705,26 +812,44 @@ bool GLES2Implementation::GetHelper(GLenum pname, GLint* params) {
*params = gl_state_.num_shader_binary_formats;
return true;
case GL_ARRAY_BUFFER_BINDING:
- *params = bound_array_buffer_id_;
- return true;
+ if (bind_generates_resource_) {
+ *params = bound_array_buffer_id_;
+ return true;
+ }
+ return false;
case GL_ELEMENT_ARRAY_BUFFER_BINDING:
- *params = bound_element_array_buffer_id_;
- return true;
+ if (bind_generates_resource_) {
+ *params = bound_element_array_buffer_id_;
+ return true;
+ }
+ return false;
case GL_ACTIVE_TEXTURE:
*params = active_texture_unit_ + GL_TEXTURE0;
return true;
case GL_TEXTURE_BINDING_2D:
- *params = texture_units_[active_texture_unit_].bound_texture_2d;
- return true;
+ if (bind_generates_resource_) {
+ *params = texture_units_[active_texture_unit_].bound_texture_2d;
+ return true;
+ }
+ return false;
case GL_TEXTURE_BINDING_CUBE_MAP:
- *params = texture_units_[active_texture_unit_].bound_texture_cube_map;
- return true;
+ if (bind_generates_resource_) {
+ *params = texture_units_[active_texture_unit_].bound_texture_cube_map;
+ return true;
+ }
+ return false;
case GL_FRAMEBUFFER_BINDING:
- *params = bound_framebuffer_;
- return true;
+ if (bind_generates_resource_) {
+ *params = bound_framebuffer_;
+ return true;
+ }
+ return false;
case GL_RENDERBUFFER_BINDING:
- *params = bound_renderbuffer_;
- return true;
+ if (bind_generates_resource_) {
+ *params = bound_renderbuffer_;
+ return true;
+ }
+ return false;
default:
return false;
}
@@ -857,13 +982,21 @@ void GLES2Implementation::GenSharedIdsCHROMIUM(
}
});
TRACE_EVENT0("gpu", "GLES2::GenSharedIdsCHROMIUM");
- GLint* id_buffer = transfer_buffer_.AllocTyped<GLint>(n);
- helper_->GenSharedIdsCHROMIUM(namespace_id, id_offset, n,
- transfer_buffer_id_,
- transfer_buffer_.GetOffset(id_buffer));
- WaitForCmd();
- memcpy(ids, id_buffer, sizeof(*ids) * n);
- transfer_buffer_.FreePendingToken(id_buffer, helper_->InsertToken());
+ GLsizei max_size = transfer_buffer_.GetLargestFreeOrPendingSize();
+ GLsizei max_num_per = max_size / sizeof(ids[0]);
+ while (n) {
+ GLsizei num = std::min(n, max_num_per);
+ GLint* id_buffer = transfer_buffer_.AllocTyped<GLint>(num);
+ helper_->GenSharedIdsCHROMIUM(
+ namespace_id, id_offset, num,
+ transfer_buffer_id_,
+ transfer_buffer_.GetOffset(id_buffer));
+ WaitForCmd();
+ memcpy(ids, id_buffer, sizeof(*ids) * num);
+ transfer_buffer_.FreePendingToken(id_buffer, helper_->InsertToken());
+ n -= num;
+ ids += num;
+ }
}
void GLES2Implementation::DeleteSharedIdsCHROMIUM(
@@ -877,13 +1010,21 @@ void GLES2Implementation::DeleteSharedIdsCHROMIUM(
}
});
TRACE_EVENT0("gpu", "GLES2::DeleteSharedIdsCHROMIUM");
- GLint* id_buffer = transfer_buffer_.AllocTyped<GLint>(n);
- memcpy(id_buffer, ids, sizeof(*ids) * n);
- helper_->DeleteSharedIdsCHROMIUM(namespace_id, n,
- transfer_buffer_id_,
- transfer_buffer_.GetOffset(id_buffer));
- WaitForCmd();
- transfer_buffer_.FreePendingToken(id_buffer, helper_->InsertToken());
+ GLsizei max_size = transfer_buffer_.GetLargestFreeOrPendingSize();
+ GLsizei max_num_per = max_size / sizeof(ids[0]);
+ while (n) {
+ GLsizei num = std::min(n, max_num_per);
+ GLint* id_buffer = transfer_buffer_.AllocTyped<GLint>(num);
+ memcpy(id_buffer, ids, sizeof(*ids) * num);
+ helper_->DeleteSharedIdsCHROMIUM(
+ namespace_id, num,
+ transfer_buffer_id_,
+ transfer_buffer_.GetOffset(id_buffer));
+ WaitForCmd();
+ transfer_buffer_.FreePendingToken(id_buffer, helper_->InsertToken());
+ n -= num;
+ ids += num;
+ }
}
void GLES2Implementation::RegisterSharedIdsCHROMIUM(
@@ -897,13 +1038,21 @@ void GLES2Implementation::RegisterSharedIdsCHROMIUM(
}
});
TRACE_EVENT0("gpu", "GLES2::RegisterSharedIdsCHROMIUM");
- GLint* id_buffer = transfer_buffer_.AllocTyped<GLint>(n);
- memcpy(id_buffer, ids, sizeof(*ids) * n);
- helper_->RegisterSharedIdsCHROMIUM(namespace_id, n,
- transfer_buffer_id_,
- transfer_buffer_.GetOffset(id_buffer));
- WaitForCmd();
- transfer_buffer_.FreePendingToken(id_buffer, helper_->InsertToken());
+ GLsizei max_size = transfer_buffer_.GetLargestFreeOrPendingSize();
+ GLsizei max_num_per = max_size / sizeof(ids[0]);
+ while (n) {
+ GLsizei num = std::min(n, max_num_per);
+ GLint* id_buffer = transfer_buffer_.AllocTyped<GLint>(n);
+ memcpy(id_buffer, ids, sizeof(*ids) * n);
+ helper_->RegisterSharedIdsCHROMIUM(
+ namespace_id, n,
+ transfer_buffer_id_,
+ transfer_buffer_.GetOffset(id_buffer));
+ WaitForCmd();
+ transfer_buffer_.FreePendingToken(id_buffer, helper_->InsertToken());
+ n -= num;
+ ids += num;
+ }
}
void GLES2Implementation::BindAttribLocation(
@@ -943,10 +1092,30 @@ void GLES2Implementation::GetVertexAttribPointerv(
});
}
-void GLES2Implementation::DeleteProgramOrShaderHelper(
- GLuint program_or_shader) {
- program_and_shader_id_handler_->FreeIds(1, &program_or_shader);
- program_info_manager_->DeleteInfo(program_or_shader);
+bool GLES2Implementation::DeleteProgramHelper(GLuint program) {
+ if (!program_and_shader_id_handler_->FreeIds(1, &program)) {
+ SetGLError(
+ GL_INVALID_VALUE,
+ "glDeleteProgram: id not created by this context.");
+ return false;
+ }
+ program_info_manager_->DeleteInfo(program);
+ helper_->DeleteProgram(program);
+ Flush();
+ return true;
+}
+
+bool GLES2Implementation::DeleteShaderHelper(GLuint shader) {
+ if (!program_and_shader_id_handler_->FreeIds(1, &shader)) {
+ SetGLError(
+ GL_INVALID_VALUE,
+ "glDeleteShader: id not created by this context.");
+ return false;
+ }
+ program_info_manager_->DeleteInfo(shader);
+ helper_->DeleteShader(shader);
+ Flush();
+ return true;
}
GLint GLES2Implementation::GetAttribLocationHelper(
@@ -1964,7 +2133,12 @@ bool GLES2Implementation::IsBufferReservedId(GLuint /* id */) {
void GLES2Implementation::DeleteBuffersHelper(
GLsizei n, const GLuint* buffers) {
- buffer_id_handler_->FreeIds(n, buffers);
+ if (!buffer_id_handler_->FreeIds(n, buffers)) {
+ SetGLError(
+ GL_INVALID_VALUE,
+ "glDeleteBuffers: id not created by this context.");
+ return;
+ }
for (GLsizei ii = 0; ii < n; ++ii) {
if (buffers[ii] == bound_array_buffer_id_) {
bound_array_buffer_id_ = 0;
@@ -1973,31 +2147,52 @@ void GLES2Implementation::DeleteBuffersHelper(
bound_element_array_buffer_id_ = 0;
}
}
+ helper_->DeleteBuffersImmediate(n, buffers);
+ Flush();
}
void GLES2Implementation::DeleteFramebuffersHelper(
GLsizei n, const GLuint* framebuffers) {
- framebuffer_id_handler_->FreeIds(n, framebuffers);
+ if (!framebuffer_id_handler_->FreeIds(n, framebuffers)) {
+ SetGLError(
+ GL_INVALID_VALUE,
+ "glDeleteFramebuffers: id not created by this context.");
+ return;
+ }
for (GLsizei ii = 0; ii < n; ++ii) {
if (framebuffers[ii] == bound_framebuffer_) {
bound_framebuffer_ = 0;
}
}
+ helper_->DeleteFramebuffersImmediate(n, framebuffers);
+ Flush();
}
void GLES2Implementation::DeleteRenderbuffersHelper(
GLsizei n, const GLuint* renderbuffers) {
- renderbuffer_id_handler_->FreeIds(n, renderbuffers);
+ if (!renderbuffer_id_handler_->FreeIds(n, renderbuffers)) {
+ SetGLError(
+ GL_INVALID_VALUE,
+ "glDeleteRenderbuffers: id not created by this context.");
+ return;
+ }
for (GLsizei ii = 0; ii < n; ++ii) {
if (renderbuffers[ii] == bound_renderbuffer_) {
bound_renderbuffer_ = 0;
}
}
+ helper_->DeleteRenderbuffersImmediate(n, renderbuffers);
+ Flush();
}
void GLES2Implementation::DeleteTexturesHelper(
GLsizei n, const GLuint* textures) {
- texture_id_handler_->FreeIds(n, textures);
+ if (!texture_id_handler_->FreeIds(n, textures)) {
+ SetGLError(
+ GL_INVALID_VALUE,
+ "glDeleteTextures: id not created by this context.");
+ return;
+ }
for (GLsizei ii = 0; ii < n; ++ii) {
for (GLint tt = 0; tt < gl_state_.max_combined_texture_image_units; ++tt) {
TextureUnit& unit = texture_units_[active_texture_unit_];
@@ -2009,6 +2204,8 @@ void GLES2Implementation::DeleteTexturesHelper(
}
}
}
+ helper_->DeleteTexturesImmediate(n, textures);
+ Flush();
}
void GLES2Implementation::DisableVertexAttribArray(GLuint index) {
@@ -2428,3 +2625,4 @@ void GLES2Implementation::GetProgramInfoCHROMIUM(
} // namespace gles2
} // namespace gpu
+
« no previous file with comments | « gpu/command_buffer/client/gles2_implementation.h ('k') | gpu/command_buffer/client/gles2_implementation_autogen.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698