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

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

Issue 162023002: Reduce internal Flush() in GL resource glGen/Delete APIs. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Revert lock_ pattern change in IdHandler::FreeIds. Created 6 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
« no previous file with comments | « gpu/command_buffer/client/share_group.h ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: gpu/command_buffer/client/share_group.cc
diff --git a/gpu/command_buffer/client/share_group.cc b/gpu/command_buffer/client/share_group.cc
index 8711ce817e64485ac76cf65115bb737be88bc8b3..96ab8d181be01ab52edda453043ad4bbd451bf78 100644
--- a/gpu/command_buffer/client/share_group.cc
+++ b/gpu/command_buffer/client/share_group.cc
@@ -2,6 +2,9 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+#include <stack>
+#include <vector>
+
#include "gpu/command_buffer/client/share_group.h"
#include "base/logging.h"
@@ -13,6 +16,9 @@
namespace gpu {
namespace gles2 {
+ShareGroupContextData::IdHandlerData::IdHandlerData() : flush_generation_(0) {}
+ShareGroupContextData::IdHandlerData::~IdHandlerData() {}
+
COMPILE_ASSERT(gpu::kInvalidResource == 0,
INVALID_RESOURCE_NOT_0_AS_GL_EXPECTS);
@@ -44,12 +50,16 @@ class IdHandler : public IdHandlerInterface {
GLES2Implementation* gl_impl,
GLsizei n, const GLuint* ids, DeleteFn delete_fn) OVERRIDE {
base::AutoLock auto_lock(lock_);
+
for (GLsizei ii = 0; ii < n; ++ii) {
id_allocator_.FreeID(ids[ii]);
}
+
(gl_impl->*delete_fn)(n, ids);
// We need to ensure that the delete call is evaluated on the service side
// before any other contexts issue commands using these client ids.
+ // TODO(vmiura): Can remove this by virtualizing internal ids, however
+ // this code only affects PPAPI for now.
gl_impl->helper()->CommandBufferHelper::Flush();
return true;
}
@@ -62,27 +72,121 @@ class IdHandler : public IdHandlerInterface {
return id_allocator_.MarkAsUsed(id);
}
- protected:
+ virtual void FreeContext(GLES2Implementation* gl_impl) OVERRIDE {}
+
+ private:
base::Lock lock_;
IdAllocator id_allocator_;
};
// An id handler that requires Gen before Bind.
-class StrictIdHandler : public IdHandler {
+class StrictIdHandler : public IdHandlerInterface {
public:
- StrictIdHandler() {}
+ explicit StrictIdHandler(int id_namespace) : id_namespace_(id_namespace) {}
virtual ~StrictIdHandler() {}
// Overridden from IdHandler.
+ virtual void MakeIds(GLES2Implementation* gl_impl,
+ GLuint /* id_offset */,
+ GLsizei n,
+ GLuint* ids) OVERRIDE {
+ base::AutoLock auto_lock(lock_);
+
+ // Collect pending FreeIds from other flush_generation.
+ CollectPendingFreeIds(gl_impl);
+
+ for (GLsizei ii = 0; ii < n; ++ii) {
+ if (!free_ids_.empty()) {
+ // Allocate a previously freed Id.
+ ids[ii] = free_ids_.top();
+ free_ids_.pop();
+
+ // Record kIdInUse state.
+ DCHECK(id_states_[ids[ii] - 1] == kIdFree);
+ id_states_[ids[ii] - 1] = kIdInUse;
+ } else {
+ // Allocate a new Id.
+ id_states_.push_back(kIdInUse);
+ ids[ii] = id_states_.size();
+ }
+ }
+ }
+
+ // Overridden from IdHandler.
+ virtual bool FreeIds(GLES2Implementation* gl_impl,
+ GLsizei n,
+ const GLuint* ids,
+ DeleteFn delete_fn) OVERRIDE {
+
+ // Delete stub must run before CollectPendingFreeIds.
+ (gl_impl->*delete_fn)(n, ids);
+
+ {
+ base::AutoLock auto_lock(lock_);
+
+ // Collect pending FreeIds from other flush_generation.
+ CollectPendingFreeIds(gl_impl);
+
+ // Save Ids to free in a later flush_generation.
+ ShareGroupContextData::IdHandlerData* ctxt_data =
+ gl_impl->share_group_context_data()->id_handler_data(id_namespace_);
+
+ for (GLsizei ii = 0; ii < n; ++ii) {
+ GLuint id = ids[ii];
+ if (id != 0) {
+ // Save freed Id for later.
+ DCHECK(id_states_[id - 1] == kIdInUse);
+ id_states_[id - 1] = kIdPendingFree;
+ ctxt_data->freed_ids_.push_back(id);
+ }
+ }
+ }
+
+ return true;
+ }
+
+ // Overridden from IdHandler.
virtual bool MarkAsUsedForBind(GLuint id) OVERRIDE {
#ifndef NDEBUG
- {
+ if (id != 0) {
base::AutoLock auto_lock(lock_);
- DCHECK(id == 0 || id_allocator_.InUse(id));
+ DCHECK(id_states_[id - 1] == kIdInUse);
}
#endif
return true;
}
+
+ // Overridden from IdHandlerInterface.
+ virtual void FreeContext(GLES2Implementation* gl_impl) OVERRIDE {
+ base::AutoLock auto_lock(lock_);
+ CollectPendingFreeIds(gl_impl);
+ }
+
+ private:
+ enum IdState { kIdFree, kIdPendingFree, kIdInUse };
+
+ void CollectPendingFreeIds(GLES2Implementation* gl_impl) {
+ uint32 flush_generation = gl_impl->helper()->flush_generation();
+ ShareGroupContextData::IdHandlerData* ctxt_data =
+ gl_impl->share_group_context_data()->id_handler_data(id_namespace_);
+
+ if (ctxt_data->flush_generation_ != flush_generation) {
+ ctxt_data->flush_generation_ = flush_generation;
+ for (uint32 ii = 0; ii < ctxt_data->freed_ids_.size(); ++ii) {
+ const GLuint id = ctxt_data->freed_ids_[ii];
+ DCHECK(id_states_[id - 1] == kIdPendingFree);
+ id_states_[id - 1] = kIdFree;
+ free_ids_.push(id);
+ }
+ ctxt_data->freed_ids_.clear();
+ }
+ }
+
+ int id_namespace_;
+
+ base::Lock lock_;
+ std::vector<uint8> id_states_;
+ std::stack<uint32> free_ids_;
};
// An id handler for ids that are never reused.
@@ -116,6 +220,8 @@ class NonReusedIdHandler : public IdHandlerInterface {
return false;
}
+ virtual void FreeContext(GLES2Implementation* gl_impl) OVERRIDE {}
+
private:
base::Lock lock_;
GLuint last_id_;
@@ -136,7 +242,7 @@ ShareGroup::ShareGroup(bool bind_generates_resource)
if (i == id_namespaces::kProgramsAndShaders) {
id_handlers_[i].reset(new NonReusedIdHandler());
} else {
- id_handlers_[i].reset(new StrictIdHandler());
+ id_handlers_[i].reset(new StrictIdHandler(i));
}
}
}
« no previous file with comments | « gpu/command_buffer/client/share_group.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698