summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authortobiasjs <tobiasjs@chromium.org>2015-08-21 17:39:06 -0700
committerCommit bot <commit-bot@chromium.org>2015-08-22 00:39:38 +0000
commitfc199b47cb5b74c9f2ccf3a6316fc9b7009c6904 (patch)
treeddebbbd1b94efa885c5e2656760911fe6460fba5
parent926097380c61018aa2d5dfc99299f592ccfa5738 (diff)
downloadchromium_src-fc199b47cb5b74c9f2ccf3a6316fc9b7009c6904.zip
chromium_src-fc199b47cb5b74c9f2ccf3a6316fc9b7009c6904.tar.gz
chromium_src-fc199b47cb5b74c9f2ccf3a6316fc9b7009c6904.tar.bz2
Fix crash caused by concurrent access to framebuffer_combo_complete_map_.
The current implementation of framebuffer completeness testing uses a single global hash_map as a cache. This leads to races in WebView when GPU and render threads try to access the cache concurrently. BUG=518858 Review URL: https://codereview.chromium.org/1278333003 Cr-Commit-Position: refs/heads/master@{#344940}
-rw-r--r--android_webview/browser/deferred_gpu_command_service.cc10
-rw-r--r--android_webview/browser/deferred_gpu_command_service.h4
-rw-r--r--components/view_manager/gles2/command_buffer_driver.cc5
-rw-r--r--components/view_manager/gles2/command_buffer_local.cc5
-rw-r--r--content/common/gpu/gpu_channel_manager.cc8
-rw-r--r--content/common/gpu/gpu_channel_manager.h4
-rw-r--r--content/common/gpu/gpu_command_buffer_stub.cc8
-rw-r--r--gpu/command_buffer/service/BUILD.gn2
-rw-r--r--gpu/command_buffer/service/context_group.cc18
-rw-r--r--gpu/command_buffer/service/context_group.h8
-rw-r--r--gpu/command_buffer/service/context_group_unittest.cc2
-rw-r--r--gpu/command_buffer/service/framebuffer_completeness_cache.cc24
-rw-r--r--gpu/command_buffer/service/framebuffer_completeness_cache.h42
-rw-r--r--gpu/command_buffer/service/framebuffer_manager.cc85
-rw-r--r--gpu/command_buffer/service/framebuffer_manager.h26
-rw-r--r--gpu/command_buffer/service/framebuffer_manager_unittest.cc37
-rw-r--r--gpu/command_buffer/service/gles2_cmd_decoder_unittest_base.cc11
-rw-r--r--gpu/command_buffer/service/in_process_command_buffer.cc15
-rw-r--r--gpu/command_buffer/service/in_process_command_buffer.h7
-rw-r--r--gpu/command_buffer/service/texture_manager_unittest.cc4
-rw-r--r--gpu/command_buffer/tests/gl_manager.cc12
-rw-r--r--gpu/command_buffer_service.gypi2
-rw-r--r--gpu/gles2_conform_support/egl/display.cc11
23 files changed, 209 insertions, 141 deletions
diff --git a/android_webview/browser/deferred_gpu_command_service.cc b/android_webview/browser/deferred_gpu_command_service.cc
index 8e0591e..ef0542c 100644
--- a/android_webview/browser/deferred_gpu_command_service.cc
+++ b/android_webview/browser/deferred_gpu_command_service.cc
@@ -10,6 +10,7 @@
#include "base/synchronization/lock.h"
#include "base/trace_event/trace_event.h"
#include "content/public/browser/android/synchronous_compositor.h"
+#include "gpu/command_buffer/service/framebuffer_completeness_cache.h"
#include "gpu/command_buffer/service/shader_translator_cache.h"
#include "gpu/command_buffer/service/sync_point_manager.h"
@@ -153,6 +154,15 @@ DeferredGpuCommandService::shader_translator_cache() {
return shader_translator_cache_;
}
+scoped_refptr<gpu::gles2::FramebufferCompletenessCache>
+DeferredGpuCommandService::framebuffer_completeness_cache() {
+ if (!framebuffer_completeness_cache_.get()) {
+ framebuffer_completeness_cache_ =
+ new gpu::gles2::FramebufferCompletenessCache;
+ }
+ return framebuffer_completeness_cache_;
+}
+
gpu::SyncPointManager* DeferredGpuCommandService::sync_point_manager() {
return sync_point_manager_.get();
}
diff --git a/android_webview/browser/deferred_gpu_command_service.h b/android_webview/browser/deferred_gpu_command_service.h
index c7f230d..395fd68 100644
--- a/android_webview/browser/deferred_gpu_command_service.h
+++ b/android_webview/browser/deferred_gpu_command_service.h
@@ -46,6 +46,8 @@ class DeferredGpuCommandService
bool UseVirtualizedGLContexts() override;
scoped_refptr<gpu::gles2::ShaderTranslatorCache> shader_translator_cache()
override;
+ scoped_refptr<gpu::gles2::FramebufferCompletenessCache>
+ framebuffer_completeness_cache() override;
gpu::SyncPointManager* sync_point_manager() override;
void RunTasks();
@@ -76,6 +78,8 @@ class DeferredGpuCommandService
scoped_ptr<gpu::SyncPointManager> sync_point_manager_;
scoped_refptr<gpu::gles2::ShaderTranslatorCache> shader_translator_cache_;
+ scoped_refptr<gpu::gles2::FramebufferCompletenessCache>
+ framebuffer_completeness_cache_;
DISALLOW_COPY_AND_ASSIGN(DeferredGpuCommandService);
};
diff --git a/components/view_manager/gles2/command_buffer_driver.cc b/components/view_manager/gles2/command_buffer_driver.cc
index 53a428a..77d2da2 100644
--- a/components/view_manager/gles2/command_buffer_driver.cc
+++ b/components/view_manager/gles2/command_buffer_driver.cc
@@ -96,8 +96,9 @@ bool CommandBufferDriver::DoInitialize(
scoped_refptr<gpu::gles2::ContextGroup> context_group =
new gpu::gles2::ContextGroup(
gpu_state_->mailbox_manager(), new GpuMemoryTracker,
- new gpu::gles2::ShaderTranslatorCache, nullptr, nullptr, nullptr,
- bind_generates_resource);
+ new gpu::gles2::ShaderTranslatorCache,
+ new gpu::gles2::FramebufferCompletenessCache, nullptr, nullptr,
+ nullptr, bind_generates_resource);
command_buffer_.reset(
new gpu::CommandBufferService(context_group->transfer_buffer_manager()));
diff --git a/components/view_manager/gles2/command_buffer_local.cc b/components/view_manager/gles2/command_buffer_local.cc
index 694bc05..86ab863 100644
--- a/components/view_manager/gles2/command_buffer_local.cc
+++ b/components/view_manager/gles2/command_buffer_local.cc
@@ -76,8 +76,9 @@ bool CommandBufferLocal::Initialize() {
scoped_refptr<gpu::gles2::ContextGroup> context_group =
new gpu::gles2::ContextGroup(
gpu_state_->mailbox_manager(), new gles2::GpuMemoryTracker,
- new gpu::gles2::ShaderTranslatorCache, nullptr, nullptr, nullptr,
- bind_generates_resource);
+ new gpu::gles2::ShaderTranslatorCache,
+ new gpu::gles2::FramebufferCompletenessCache, nullptr, nullptr,
+ nullptr, bind_generates_resource);
command_buffer_.reset(
new gpu::CommandBufferService(context_group->transfer_buffer_manager()));
diff --git a/content/common/gpu/gpu_channel_manager.cc b/content/common/gpu/gpu_channel_manager.cc
index 040deb9..21672e2 100644
--- a/content/common/gpu/gpu_channel_manager.cc
+++ b/content/common/gpu/gpu_channel_manager.cc
@@ -79,6 +79,14 @@ GpuChannelManager::shader_translator_cache() {
return shader_translator_cache_.get();
}
+gpu::gles2::FramebufferCompletenessCache*
+GpuChannelManager::framebuffer_completeness_cache() {
+ if (!framebuffer_completeness_cache_.get())
+ framebuffer_completeness_cache_ =
+ new gpu::gles2::FramebufferCompletenessCache;
+ return framebuffer_completeness_cache_.get();
+}
+
void GpuChannelManager::RemoveChannel(int client_id) {
Send(new GpuHostMsg_DestroyChannel(client_id));
gpu_channels_.erase(client_id);
diff --git a/content/common/gpu/gpu_channel_manager.h b/content/common/gpu/gpu_channel_manager.h
index f90a76d..a611a94 100644
--- a/content/common/gpu/gpu_channel_manager.h
+++ b/content/common/gpu/gpu_channel_manager.h
@@ -35,6 +35,7 @@ namespace gpu {
class SyncPointManager;
union ValueState;
namespace gles2 {
+class FramebufferCompletenessCache;
class MailboxManager;
class ProgramCache;
class ShaderTranslatorCache;
@@ -92,6 +93,7 @@ class CONTENT_EXPORT GpuChannelManager : public IPC::Listener,
gpu::gles2::ProgramCache* program_cache();
gpu::gles2::ShaderTranslatorCache* shader_translator_cache();
+ gpu::gles2::FramebufferCompletenessCache* framebuffer_completeness_cache();
GpuMemoryManager* gpu_memory_manager() { return &gpu_memory_manager_; }
@@ -157,6 +159,8 @@ class CONTENT_EXPORT GpuChannelManager : public IPC::Listener,
gpu::SyncPointManager* sync_point_manager_;
scoped_ptr<gpu::gles2::ProgramCache> program_cache_;
scoped_refptr<gpu::gles2::ShaderTranslatorCache> shader_translator_cache_;
+ scoped_refptr<gpu::gles2::FramebufferCompletenessCache>
+ framebuffer_completeness_cache_;
scoped_refptr<gfx::GLSurface> default_offscreen_surface_;
GpuMemoryBufferFactory* const gpu_memory_buffer_factory_;
IPC::SyncChannel* channel_;
diff --git a/content/common/gpu/gpu_command_buffer_stub.cc b/content/common/gpu/gpu_command_buffer_stub.cc
index c1b0127..d410eb7 100644
--- a/content/common/gpu/gpu_command_buffer_stub.cc
+++ b/content/common/gpu/gpu_command_buffer_stub.cc
@@ -209,12 +209,10 @@ GpuCommandBufferStub::GpuCommandBufferStub(
attrib_parser.bind_generates_resource);
} else {
context_group_ = new gpu::gles2::ContextGroup(
- mailbox_manager,
- new GpuCommandBufferMemoryTracker(channel),
+ mailbox_manager, new GpuCommandBufferMemoryTracker(channel),
channel_->gpu_channel_manager()->shader_translator_cache(),
- NULL,
- subscription_ref_set,
- pending_valuebuffer_state,
+ channel_->gpu_channel_manager()->framebuffer_completeness_cache(), NULL,
+ subscription_ref_set, pending_valuebuffer_state,
attrib_parser.bind_generates_resource);
}
diff --git a/gpu/command_buffer/service/BUILD.gn b/gpu/command_buffer/service/BUILD.gn
index 7a2e2b2..1acdb1b 100644
--- a/gpu/command_buffer/service/BUILD.gn
+++ b/gpu/command_buffer/service/BUILD.gn
@@ -59,6 +59,8 @@ source_set("service_sources") {
"error_state.h",
"feature_info.cc",
"feature_info.h",
+ "framebuffer_completeness_cache.cc",
+ "framebuffer_completeness_cache.h",
"framebuffer_manager.cc",
"framebuffer_manager.h",
"gl_context_virtual.cc",
diff --git a/gpu/command_buffer/service/context_group.cc b/gpu/command_buffer/service/context_group.cc
index ca8b335..530488e 100644
--- a/gpu/command_buffer/service/context_group.cc
+++ b/gpu/command_buffer/service/context_group.cc
@@ -30,6 +30,8 @@ ContextGroup::ContextGroup(
const scoped_refptr<MailboxManager>& mailbox_manager,
const scoped_refptr<MemoryTracker>& memory_tracker,
const scoped_refptr<ShaderTranslatorCache>& shader_translator_cache,
+ const scoped_refptr<FramebufferCompletenessCache>&
+ framebuffer_completeness_cache,
const scoped_refptr<FeatureInfo>& feature_info,
const scoped_refptr<SubscriptionRefSet>& subscription_ref_set,
const scoped_refptr<ValueStateMap>& pending_valuebuffer_state,
@@ -38,6 +40,17 @@ ContextGroup::ContextGroup(
mailbox_manager_(mailbox_manager),
memory_tracker_(memory_tracker),
shader_translator_cache_(shader_translator_cache),
+#if defined(OS_MACOSX)
+ // Framebuffer completeness is not cacheable on OS X because of dynamic
+ // graphics switching.
+ // http://crbug.com/180876
+ // TODO(tobiasjs): determine whether GPU switching is possible
+ // programmatically, rather than just hardcoding this behaviour
+ // for OS X.
+ framebuffer_completeness_cache_(NULL),
+#else
+ framebuffer_completeness_cache_(framebuffer_completeness_cache),
+#endif
subscription_ref_set_(subscription_ref_set),
pending_valuebuffer_state_(pending_valuebuffer_state),
enforce_gl_minimums_(
@@ -154,8 +167,9 @@ bool ContextGroup::Initialize(
buffer_manager_.reset(
new BufferManager(memory_tracker_.get(), feature_info_.get()));
- framebuffer_manager_.reset(new FramebufferManager(
- max_draw_buffers_, max_color_attachments_, context_type));
+ framebuffer_manager_.reset(
+ new FramebufferManager(max_draw_buffers_, max_color_attachments_,
+ context_type, framebuffer_completeness_cache_));
renderbuffer_manager_.reset(new RenderbufferManager(
memory_tracker_.get(), max_renderbuffer_size, max_samples,
feature_info_.get()));
diff --git a/gpu/command_buffer/service/context_group.h b/gpu/command_buffer/service/context_group.h
index ea62823..7625970 100644
--- a/gpu/command_buffer/service/context_group.h
+++ b/gpu/command_buffer/service/context_group.h
@@ -14,6 +14,7 @@
#include "gpu/command_buffer/common/constants.h"
#include "gpu/command_buffer/common/gles2_cmd_format.h"
#include "gpu/command_buffer/service/feature_info.h"
+#include "gpu/command_buffer/service/framebuffer_completeness_cache.h"
#include "gpu/command_buffer/service/shader_translator_cache.h"
#include "gpu/gpu_export.h"
@@ -56,6 +57,8 @@ class GPU_EXPORT ContextGroup : public base::RefCounted<ContextGroup> {
const scoped_refptr<MailboxManager>& mailbox_manager,
const scoped_refptr<MemoryTracker>& memory_tracker,
const scoped_refptr<ShaderTranslatorCache>& shader_translator_cache,
+ const scoped_refptr<FramebufferCompletenessCache>&
+ framebuffer_completeness_cache,
const scoped_refptr<FeatureInfo>& feature_info,
const scoped_refptr<SubscriptionRefSet>& subscription_ref_set,
const scoped_refptr<ValueStateMap>& pending_valuebuffer_state,
@@ -84,6 +87,10 @@ class GPU_EXPORT ContextGroup : public base::RefCounted<ContextGroup> {
return shader_translator_cache_.get();
}
+ FramebufferCompletenessCache* framebuffer_completeness_cache() const {
+ return framebuffer_completeness_cache_.get();
+ }
+
bool bind_generates_resource() {
return bind_generates_resource_;
}
@@ -257,6 +264,7 @@ class GPU_EXPORT ContextGroup : public base::RefCounted<ContextGroup> {
scoped_refptr<MailboxManager> mailbox_manager_;
scoped_refptr<MemoryTracker> memory_tracker_;
scoped_refptr<ShaderTranslatorCache> shader_translator_cache_;
+ scoped_refptr<FramebufferCompletenessCache> framebuffer_completeness_cache_;
scoped_refptr<TransferBufferManagerInterface> transfer_buffer_manager_;
scoped_refptr<SubscriptionRefSet> subscription_ref_set_;
scoped_refptr<ValueStateMap> pending_valuebuffer_state_;
diff --git a/gpu/command_buffer/service/context_group_unittest.cc b/gpu/command_buffer/service/context_group_unittest.cc
index 7c6d5c1..cbb36f5 100644
--- a/gpu/command_buffer/service/context_group_unittest.cc
+++ b/gpu/command_buffer/service/context_group_unittest.cc
@@ -41,7 +41,7 @@ class ContextGroupTest : public GpuServiceTest {
GpuServiceTest::SetUp();
decoder_.reset(new MockGLES2Decoder());
group_ = scoped_refptr<ContextGroup>(new ContextGroup(
- NULL, NULL, NULL, NULL, NULL, NULL, kBindGeneratesResource));
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, kBindGeneratesResource));
}
scoped_ptr<MockGLES2Decoder> decoder_;
diff --git a/gpu/command_buffer/service/framebuffer_completeness_cache.cc b/gpu/command_buffer/service/framebuffer_completeness_cache.cc
new file mode 100644
index 0000000..183b023
--- /dev/null
+++ b/gpu/command_buffer/service/framebuffer_completeness_cache.cc
@@ -0,0 +1,24 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "gpu/command_buffer/service/framebuffer_completeness_cache.h"
+
+namespace gpu {
+namespace gles2 {
+
+FramebufferCompletenessCache::FramebufferCompletenessCache() {}
+
+FramebufferCompletenessCache::~FramebufferCompletenessCache() {}
+
+bool FramebufferCompletenessCache::IsComplete(
+ const std::string& signature) const {
+ return cache_.find(signature) != cache_.end();
+}
+
+void FramebufferCompletenessCache::SetComplete(const std::string& signature) {
+ cache_.insert(signature);
+}
+
+} // namespace gles2
+} // namespace gpu
diff --git a/gpu/command_buffer/service/framebuffer_completeness_cache.h b/gpu/command_buffer/service/framebuffer_completeness_cache.h
new file mode 100644
index 0000000..7200cbd
--- /dev/null
+++ b/gpu/command_buffer/service/framebuffer_completeness_cache.h
@@ -0,0 +1,42 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef GPU_COMMAND_BUFFER_SERVICE_FRAMEBUFFER_COMPLETENESS_CACHE_H_
+#define GPU_COMMAND_BUFFER_SERVICE_FRAMEBUFFER_COMPLETENESS_CACHE_H_
+
+#include "base/containers/hash_tables.h"
+#include "base/memory/ref_counted.h"
+#include "gpu/gpu_export.h"
+
+namespace gpu {
+namespace gles2 {
+
+// Refcounted wrapper for a hash_set of framebuffer format signatures
+// representing framebuffer configurations that are reported by the GL
+// driver as complete according to glCheckFramebufferStatusEXT.
+class GPU_EXPORT FramebufferCompletenessCache
+ : public base::RefCounted<FramebufferCompletenessCache> {
+ public:
+ FramebufferCompletenessCache();
+
+ bool IsComplete(const std::string& signature) const;
+ void SetComplete(const std::string& signature);
+
+ protected:
+ virtual ~FramebufferCompletenessCache();
+
+ private:
+ friend class base::RefCounted<FramebufferCompletenessCache>;
+
+ typedef base::hash_set<std::string> Map;
+
+ Map cache_;
+
+ DISALLOW_COPY_AND_ASSIGN(FramebufferCompletenessCache);
+};
+
+} // namespace gles2
+} // namespace gpu
+
+#endif // GPU_COMMAND_BUFFER_SERVICE_FRAMEBUFFER_COMPLETENESS_CACHE_H_
diff --git a/gpu/command_buffer/service/framebuffer_manager.cc b/gpu/command_buffer/service/framebuffer_manager.cc
index 9a1b77c..9c3a522 100644
--- a/gpu/command_buffer/service/framebuffer_manager.cc
+++ b/gpu/command_buffer/service/framebuffer_manager.cc
@@ -6,6 +6,7 @@
#include "base/logging.h"
#include "base/strings/stringprintf.h"
#include "gpu/command_buffer/common/gles2_cmd_utils.h"
+#include "gpu/command_buffer/service/framebuffer_completeness_cache.h"
#include "gpu/command_buffer/service/renderbuffer_manager.h"
#include "gpu/command_buffer/service/texture_manager.h"
#include "ui/gl/gl_bindings.h"
@@ -22,24 +23,6 @@ DecoderFramebufferState::DecoderFramebufferState()
DecoderFramebufferState::~DecoderFramebufferState() {
}
-Framebuffer::FramebufferComboCompleteMap*
- Framebuffer::framebuffer_combo_complete_map_;
-
-// Framebuffer completeness is not cacheable on OS X because of dynamic
-// graphics switching.
-// http://crbug.com/180876
-#if defined(OS_MACOSX)
-bool Framebuffer::allow_framebuffer_combo_complete_map_ = false;
-#else
-bool Framebuffer::allow_framebuffer_combo_complete_map_ = true;
-#endif
-
-void Framebuffer::ClearFramebufferCompleteComboMap() {
- if (framebuffer_combo_complete_map_) {
- framebuffer_combo_complete_map_->clear();
- }
-}
-
class RenderbufferAttachment
: public Framebuffer::Attachment {
public:
@@ -260,14 +243,18 @@ FramebufferManager::TextureDetachObserver::TextureDetachObserver() {}
FramebufferManager::TextureDetachObserver::~TextureDetachObserver() {}
FramebufferManager::FramebufferManager(
- uint32 max_draw_buffers, uint32 max_color_attachments,
- ContextGroup::ContextType context_type)
+ uint32 max_draw_buffers,
+ uint32 max_color_attachments,
+ ContextGroup::ContextType context_type,
+ const scoped_refptr<FramebufferCompletenessCache>&
+ framebuffer_combo_complete_cache)
: framebuffer_state_change_count_(1),
framebuffer_count_(0),
have_context_(true),
max_draw_buffers_(max_draw_buffers),
max_color_attachments_(max_color_attachments),
- context_type_(context_type) {
+ context_type_(context_type),
+ framebuffer_combo_complete_cache_(framebuffer_combo_complete_cache) {
DCHECK_GT(max_draw_buffers_, 0u);
DCHECK_GT(max_color_attachments_, 0u);
}
@@ -503,46 +490,40 @@ GLenum Framebuffer::IsPossiblyComplete() const {
GLenum Framebuffer::GetStatus(
TextureManager* texture_manager, GLenum target) const {
+ if (!manager_->GetFramebufferComboCompleteCache()) {
+ return glCheckFramebufferStatusEXT(target);
+ }
// Check if we have this combo already.
std::string signature;
- if (allow_framebuffer_combo_complete_map_) {
- size_t signature_size = sizeof(target);
- for (AttachmentMap::const_iterator it = attachments_.begin();
- it != attachments_.end(); ++it) {
- Attachment* attachment = it->second.get();
- signature_size += sizeof(it->first) +
- attachment->GetSignatureSize(texture_manager);
- }
- signature.reserve(signature_size);
- signature.append(reinterpret_cast<const char*>(&target), sizeof(target));
+ size_t signature_size = sizeof(target);
+ for (AttachmentMap::const_iterator it = attachments_.begin();
+ it != attachments_.end(); ++it) {
+ Attachment* attachment = it->second.get();
+ signature_size +=
+ sizeof(it->first) + attachment->GetSignatureSize(texture_manager);
+ }
- for (AttachmentMap::const_iterator it = attachments_.begin();
- it != attachments_.end(); ++it) {
- Attachment* attachment = it->second.get();
- signature.append(reinterpret_cast<const char*>(&it->first),
- sizeof(it->first));
- attachment->AddToSignature(texture_manager, &signature);
- }
- DCHECK(signature.size() == signature_size);
+ signature.reserve(signature_size);
+ signature.append(reinterpret_cast<const char*>(&target), sizeof(target));
- if (!framebuffer_combo_complete_map_) {
- framebuffer_combo_complete_map_ = new FramebufferComboCompleteMap();
- }
+ for (AttachmentMap::const_iterator it = attachments_.begin();
+ it != attachments_.end(); ++it) {
+ Attachment* attachment = it->second.get();
+ signature.append(reinterpret_cast<const char*>(&it->first),
+ sizeof(it->first));
+ attachment->AddToSignature(texture_manager, &signature);
+ }
+ DCHECK(signature.size() == signature_size);
- FramebufferComboCompleteMap::const_iterator it =
- framebuffer_combo_complete_map_->find(signature);
- if (it != framebuffer_combo_complete_map_->end()) {
- return GL_FRAMEBUFFER_COMPLETE;
- }
+ if (manager_->GetFramebufferComboCompleteCache()->IsComplete(signature)) {
+ return GL_FRAMEBUFFER_COMPLETE;
}
GLenum result = glCheckFramebufferStatusEXT(target);
- // Insert the new result into the combo map.
- if (allow_framebuffer_combo_complete_map_ &&
- result == GL_FRAMEBUFFER_COMPLETE) {
- framebuffer_combo_complete_map_->insert(std::make_pair(signature, true));
+ if (result == GL_FRAMEBUFFER_COMPLETE) {
+ manager_->GetFramebufferComboCompleteCache()->SetComplete(signature);
}
return result;
@@ -778,5 +759,3 @@ void FramebufferManager::OnTextureRefDetached(TextureRef* texture) {
} // namespace gles2
} // namespace gpu
-
-
diff --git a/gpu/command_buffer/service/framebuffer_manager.h b/gpu/command_buffer/service/framebuffer_manager.h
index 9bf440a..0432584 100644
--- a/gpu/command_buffer/service/framebuffer_manager.h
+++ b/gpu/command_buffer/service/framebuffer_manager.h
@@ -18,6 +18,7 @@
namespace gpu {
namespace gles2 {
+class FramebufferCompletenessCache;
class FramebufferManager;
class Renderbuffer;
class RenderbufferManager;
@@ -156,12 +157,6 @@ class GPU_EXPORT Framebuffer : public base::RefCounted<Framebuffer> {
// formats.
bool HasSameInternalFormatsMRT() const;
- static void ClearFramebufferCompleteComboMap();
-
- static bool AllowFramebufferComboCompleteMapForTesting() {
- return allow_framebuffer_combo_complete_map_;
- }
-
void OnTextureRefDetached(TextureRef* texture);
void OnWillRenderTo() const;
void OnDidRenderTo() const;
@@ -217,12 +212,6 @@ class GPU_EXPORT Framebuffer : public base::RefCounted<Framebuffer> {
typedef base::hash_map<GLenum, scoped_refptr<Attachment> > AttachmentMap;
AttachmentMap attachments_;
- // A map of successful frame buffer combos. If it's in the map
- // it should be FRAMEBUFFER_COMPLETE.
- typedef base::hash_map<std::string, bool> FramebufferComboCompleteMap;
- static FramebufferComboCompleteMap* framebuffer_combo_complete_map_;
- static bool allow_framebuffer_combo_complete_map_;
-
scoped_ptr<GLenum[]> draw_buffers_;
GLenum read_buffer_;
@@ -258,8 +247,11 @@ class GPU_EXPORT FramebufferManager {
DISALLOW_COPY_AND_ASSIGN(TextureDetachObserver);
};
- FramebufferManager(uint32 max_draw_buffers, uint32 max_color_attachments,
- ContextGroup::ContextType context_type);
+ FramebufferManager(uint32 max_draw_buffers,
+ uint32 max_color_attachments,
+ ContextGroup::ContextType context_type,
+ const scoped_refptr<FramebufferCompletenessCache>&
+ framebuffer_combo_complete_cache);
~FramebufferManager();
// Must call before destruction.
@@ -316,6 +308,10 @@ class GPU_EXPORT FramebufferManager {
void OnTextureRefDetached(TextureRef* texture);
+ FramebufferCompletenessCache* GetFramebufferComboCompleteCache() {
+ return framebuffer_combo_complete_cache_.get();
+ }
+
// Info for each framebuffer in the system.
typedef base::hash_map<GLuint, scoped_refptr<Framebuffer> >
FramebufferMap;
@@ -339,6 +335,8 @@ class GPU_EXPORT FramebufferManager {
typedef std::vector<TextureDetachObserver*> TextureDetachObserverVector;
TextureDetachObserverVector texture_detach_observers_;
+ scoped_refptr<FramebufferCompletenessCache> framebuffer_combo_complete_cache_;
+
DISALLOW_COPY_AND_ASSIGN(FramebufferManager);
};
diff --git a/gpu/command_buffer/service/framebuffer_manager_unittest.cc b/gpu/command_buffer/service/framebuffer_manager_unittest.cc
index c7133ac..c423764 100644
--- a/gpu/command_buffer/service/framebuffer_manager_unittest.cc
+++ b/gpu/command_buffer/service/framebuffer_manager_unittest.cc
@@ -34,7 +34,7 @@ const bool kUseDefaultTextures = false;
class FramebufferManagerTest : public GpuServiceTest {
public:
FramebufferManagerTest()
- : manager_(1, 1, ContextGroup::CONTEXT_TYPE_UNDEFINED),
+ : manager_(1, 1, ContextGroup::CONTEXT_TYPE_UNDEFINED, NULL),
feature_info_(new FeatureInfo()) {
texture_manager_.reset(new TextureManager(NULL,
feature_info_.get(),
@@ -111,7 +111,10 @@ class FramebufferInfoTestBase : public GpuServiceTest {
static const GLuint kService1Id = 11;
explicit FramebufferInfoTestBase(ContextGroup::ContextType context_type)
- : manager_(kMaxDrawBuffers, kMaxColorAttachments, context_type),
+ : manager_(kMaxDrawBuffers,
+ kMaxColorAttachments,
+ context_type,
+ new FramebufferCompletenessCache),
feature_info_(new FeatureInfo()) {
texture_manager_.reset(new TextureManager(NULL,
feature_info_.get(),
@@ -835,11 +838,6 @@ TEST_F(FramebufferInfoTest, GetStatus) {
framebuffer_->GetStatus(texture_manager_.get(), GL_FRAMEBUFFER);
// Check a second call for the same type does not call anything
- if (!framebuffer_->AllowFramebufferComboCompleteMapForTesting()) {
- EXPECT_CALL(*gl_, CheckFramebufferStatusEXT(GL_FRAMEBUFFER))
- .WillOnce(Return(GL_FRAMEBUFFER_COMPLETE))
- .RetiresOnSaturation();
- }
framebuffer_->GetStatus(texture_manager_.get(), GL_FRAMEBUFFER);
// Check changing the attachments calls CheckFramebufferStatus.
@@ -850,11 +848,6 @@ TEST_F(FramebufferInfoTest, GetStatus) {
framebuffer_->GetStatus(texture_manager_.get(), GL_FRAMEBUFFER);
// Check a second call for the same type does not call anything.
- if (!framebuffer_->AllowFramebufferComboCompleteMapForTesting()) {
- EXPECT_CALL(*gl_, CheckFramebufferStatusEXT(GL_FRAMEBUFFER))
- .WillOnce(Return(GL_FRAMEBUFFER_COMPLETE))
- .RetiresOnSaturation();
- }
framebuffer_->GetStatus(texture_manager_.get(), GL_FRAMEBUFFER);
// Check a second call with a different target calls CheckFramebufferStatus.
@@ -864,11 +857,6 @@ TEST_F(FramebufferInfoTest, GetStatus) {
framebuffer_->GetStatus(texture_manager_.get(), GL_READ_FRAMEBUFFER);
// Check a second call for the same type does not call anything.
- if (!framebuffer_->AllowFramebufferComboCompleteMapForTesting()) {
- EXPECT_CALL(*gl_, CheckFramebufferStatusEXT(GL_READ_FRAMEBUFFER))
- .WillOnce(Return(GL_FRAMEBUFFER_COMPLETE))
- .RetiresOnSaturation();
- }
framebuffer_->GetStatus(texture_manager_.get(), GL_READ_FRAMEBUFFER);
// Check adding another attachment calls CheckFramebufferStatus.
@@ -879,11 +867,6 @@ TEST_F(FramebufferInfoTest, GetStatus) {
framebuffer_->GetStatus(texture_manager_.get(), GL_READ_FRAMEBUFFER);
// Check a second call for the same type does not call anything.
- if (!framebuffer_->AllowFramebufferComboCompleteMapForTesting()) {
- EXPECT_CALL(*gl_, CheckFramebufferStatusEXT(GL_READ_FRAMEBUFFER))
- .WillOnce(Return(GL_FRAMEBUFFER_COMPLETE))
- .RetiresOnSaturation();
- }
framebuffer_->GetStatus(texture_manager_.get(), GL_READ_FRAMEBUFFER);
// Check changing the format calls CheckFramebuffferStatus.
@@ -906,11 +889,6 @@ TEST_F(FramebufferInfoTest, GetStatus) {
framebuffer_->GetStatus(texture_manager_.get(), GL_READ_FRAMEBUFFER);
// Check putting it back does not call CheckFramebufferStatus.
- if (!framebuffer_->AllowFramebufferComboCompleteMapForTesting()) {
- EXPECT_CALL(*gl_, CheckFramebufferStatusEXT(GL_READ_FRAMEBUFFER))
- .WillOnce(Return(GL_FRAMEBUFFER_COMPLETE))
- .RetiresOnSaturation();
- }
TestHelper::SetTexParameteriWithExpectations(gl_.get(),
error_state_.get(),
texture_manager_.get(),
@@ -922,11 +900,6 @@ TEST_F(FramebufferInfoTest, GetStatus) {
// Check Unbinding does not call CheckFramebufferStatus
framebuffer_->UnbindRenderbuffer(GL_RENDERBUFFER, renderbuffer1);
- if (!framebuffer_->AllowFramebufferComboCompleteMapForTesting()) {
- EXPECT_CALL(*gl_, CheckFramebufferStatusEXT(GL_READ_FRAMEBUFFER))
- .WillOnce(Return(GL_FRAMEBUFFER_COMPLETE))
- .RetiresOnSaturation();
- }
framebuffer_->GetStatus(texture_manager_.get(), GL_READ_FRAMEBUFFER);
}
diff --git a/gpu/command_buffer/service/gles2_cmd_decoder_unittest_base.cc b/gpu/command_buffer/service/gles2_cmd_decoder_unittest_base.cc
index d78ec98..502d076 100644
--- a/gpu/command_buffer/service/gles2_cmd_decoder_unittest_base.cc
+++ b/gpu/command_buffer/service/gles2_cmd_decoder_unittest_base.cc
@@ -174,8 +174,6 @@ void GLES2DecoderTestBase::InitDecoderWithCommandLine(
// For easier substring/extension matching
DCHECK(normalized_init.extensions.empty() ||
*normalized_init.extensions.rbegin() == ' ');
- Framebuffer::ClearFramebufferCompleteComboMap();
-
gfx::SetGLGetProcAddressProc(gfx::MockGLInterface::GetGLProcAddress);
gfx::GLSurfaceTestSupport::InitializeOneOffWithMockBindings();
@@ -188,12 +186,9 @@ void GLES2DecoderTestBase::InitDecoderWithCommandLine(
if (command_line)
feature_info = new FeatureInfo(*command_line);
group_ = scoped_refptr<ContextGroup>(
- new ContextGroup(NULL,
- memory_tracker_,
- new ShaderTranslatorCache,
- feature_info.get(),
- new SubscriptionRefSet,
- new ValueStateMap,
+ new ContextGroup(NULL, memory_tracker_, new ShaderTranslatorCache,
+ new FramebufferCompletenessCache, feature_info.get(),
+ new SubscriptionRefSet, new ValueStateMap,
normalized_init.bind_generates_resource));
bool use_default_textures = normalized_init.bind_generates_resource;
diff --git a/gpu/command_buffer/service/in_process_command_buffer.cc b/gpu/command_buffer/service/in_process_command_buffer.cc
index d7810a4..fad09c8 100644
--- a/gpu/command_buffer/service/in_process_command_buffer.cc
+++ b/gpu/command_buffer/service/in_process_command_buffer.cc
@@ -299,11 +299,10 @@ bool InProcessCommandBuffer::InitializeOnGpuThread(
decoder_.reset(gles2::GLES2Decoder::Create(
params.context_group
? params.context_group->decoder_->GetContextGroup()
- : new gles2::ContextGroup(service_->mailbox_manager(),
- NULL,
+ : new gles2::ContextGroup(service_->mailbox_manager(), NULL,
service_->shader_translator_cache(),
- NULL,
- service_->subscription_ref_set(),
+ service_->framebuffer_completeness_cache(),
+ NULL, service_->subscription_ref_set(),
service_->pending_valuebuffer_state(),
bind_generates_resource)));
@@ -925,6 +924,14 @@ GpuInProcessThread::shader_translator_cache() {
return shader_translator_cache_;
}
+scoped_refptr<gles2::FramebufferCompletenessCache>
+GpuInProcessThread::framebuffer_completeness_cache() {
+ if (!framebuffer_completeness_cache_.get())
+ framebuffer_completeness_cache_ =
+ new gpu::gles2::FramebufferCompletenessCache;
+ return framebuffer_completeness_cache_;
+}
+
SyncPointManager* GpuInProcessThread::sync_point_manager() {
return sync_point_manager_;
}
diff --git a/gpu/command_buffer/service/in_process_command_buffer.h b/gpu/command_buffer/service/in_process_command_buffer.h
index 4dfee19..79c81e0 100644
--- a/gpu/command_buffer/service/in_process_command_buffer.h
+++ b/gpu/command_buffer/service/in_process_command_buffer.h
@@ -51,6 +51,7 @@ class SyncPointManager;
class ValueStateMap;
namespace gles2 {
+class FramebufferCompletenessCache;
class GLES2Decoder;
class MailboxManager;
class ShaderTranslatorCache;
@@ -144,6 +145,8 @@ class GPU_EXPORT InProcessCommandBuffer : public CommandBuffer,
virtual bool UseVirtualizedGLContexts() = 0;
virtual scoped_refptr<gles2::ShaderTranslatorCache>
shader_translator_cache() = 0;
+ virtual scoped_refptr<gles2::FramebufferCompletenessCache>
+ framebuffer_completeness_cache() = 0;
virtual SyncPointManager* sync_point_manager() = 0;
scoped_refptr<gfx::GLShareGroup> share_group();
scoped_refptr<gles2::MailboxManager> mailbox_manager();
@@ -279,6 +282,8 @@ class GPU_EXPORT GpuInProcessThread
bool UseVirtualizedGLContexts() override;
scoped_refptr<gles2::ShaderTranslatorCache> shader_translator_cache()
override;
+ scoped_refptr<gles2::FramebufferCompletenessCache>
+ framebuffer_completeness_cache() override;
SyncPointManager* sync_point_manager() override;
private:
@@ -287,6 +292,8 @@ class GPU_EXPORT GpuInProcessThread
SyncPointManager* sync_point_manager_; // Non-owning.
scoped_refptr<gpu::gles2::ShaderTranslatorCache> shader_translator_cache_;
+ scoped_refptr<gpu::gles2::FramebufferCompletenessCache>
+ framebuffer_completeness_cache_;
DISALLOW_COPY_AND_ASSIGN(GpuInProcessThread);
};
diff --git a/gpu/command_buffer/service/texture_manager_unittest.cc b/gpu/command_buffer/service/texture_manager_unittest.cc
index 6cadd97..231fc04 100644
--- a/gpu/command_buffer/service/texture_manager_unittest.cc
+++ b/gpu/command_buffer/service/texture_manager_unittest.cc
@@ -1923,10 +1923,10 @@ TEST_F(SharedTextureTest, TextureSafetyAccounting) {
TEST_F(SharedTextureTest, FBOCompletenessCheck) {
const GLenum kCompleteValue = GL_FRAMEBUFFER_COMPLETE;
FramebufferManager framebuffer_manager1(
- 1, 1, ContextGroup::CONTEXT_TYPE_UNDEFINED);
+ 1, 1, ContextGroup::CONTEXT_TYPE_UNDEFINED, NULL);
texture_manager1_->set_framebuffer_manager(&framebuffer_manager1);
FramebufferManager framebuffer_manager2(
- 1, 1, ContextGroup::CONTEXT_TYPE_UNDEFINED);
+ 1, 1, ContextGroup::CONTEXT_TYPE_UNDEFINED, NULL);
texture_manager2_->set_framebuffer_manager(&framebuffer_manager2);
scoped_refptr<TextureRef> ref1 = texture_manager1_->CreateTexture(10, 10);
diff --git a/gpu/command_buffer/tests/gl_manager.cc b/gpu/command_buffer/tests/gl_manager.cc
index 82930cd..539bca3 100644
--- a/gpu/command_buffer/tests/gl_manager.cc
+++ b/gpu/command_buffer/tests/gl_manager.cc
@@ -270,14 +270,10 @@ void GLManager::InitializeWithCommandLine(const GLManager::Options& options,
scoped_refptr<gles2::FeatureInfo> feature_info;
if (command_line)
feature_info = new gles2::FeatureInfo(*command_line);
- context_group =
- new gles2::ContextGroup(mailbox_manager_.get(),
- NULL,
- new gpu::gles2::ShaderTranslatorCache,
- feature_info,
- NULL,
- NULL,
- options.bind_generates_resource);
+ context_group = new gles2::ContextGroup(
+ mailbox_manager_.get(), NULL, new gpu::gles2::ShaderTranslatorCache,
+ new gpu::gles2::FramebufferCompletenessCache, feature_info, NULL, NULL,
+ options.bind_generates_resource);
}
decoder_.reset(::gpu::gles2::GLES2Decoder::Create(context_group));
diff --git a/gpu/command_buffer_service.gypi b/gpu/command_buffer_service.gypi
index b633f89..699480e 100644
--- a/gpu/command_buffer_service.gypi
+++ b/gpu/command_buffer_service.gypi
@@ -61,6 +61,8 @@
'command_buffer/service/error_state.h',
'command_buffer/service/feature_info.cc',
'command_buffer/service/feature_info.h',
+ "command_buffer/service/framebuffer_completeness_cache.cc",
+ "command_buffer/service/framebuffer_completeness_cache.h",
'command_buffer/service/framebuffer_manager.cc',
'command_buffer/service/framebuffer_manager.h',
'command_buffer/service/gl_context_virtual.cc',
diff --git a/gpu/gles2_conform_support/egl/display.cc b/gpu/gles2_conform_support/egl/display.cc
index dce6599..59e72ea 100644
--- a/gpu/gles2_conform_support/egl/display.cc
+++ b/gpu/gles2_conform_support/egl/display.cc
@@ -116,14 +116,9 @@ EGLSurface Display::CreateWindowSurface(EGLConfig config,
if (!command_buffer->Initialize())
return NULL;
- scoped_refptr<gpu::gles2::ContextGroup> group(
- new gpu::gles2::ContextGroup(NULL,
- NULL,
- new gpu::gles2::ShaderTranslatorCache,
- NULL,
- NULL,
- NULL,
- true));
+ scoped_refptr<gpu::gles2::ContextGroup> group(new gpu::gles2::ContextGroup(
+ NULL, NULL, new gpu::gles2::ShaderTranslatorCache,
+ new gpu::gles2::FramebufferCompletenessCache, NULL, NULL, NULL, true));
decoder_.reset(gpu::gles2::GLES2Decoder::Create(group.get()));
if (!decoder_.get())