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

Unified Diff: Source/platform/graphics/gpu/DrawingBuffer.cpp

Issue 169933002: WebGL: Don't destroy mailbox textures in the destructor until they're released. (Closed) Base URL: https://chromium.googlesource.com/chromium/blink.git@master
Patch Set: Improve comment. make m_recycledMailboxQueue more succinct. Created 6 years, 8 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 | « Source/platform/graphics/gpu/DrawingBuffer.h ('k') | Source/platform/graphics/gpu/DrawingBufferTest.cpp » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: Source/platform/graphics/gpu/DrawingBuffer.cpp
diff --git a/Source/platform/graphics/gpu/DrawingBuffer.cpp b/Source/platform/graphics/gpu/DrawingBuffer.cpp
index 607a68216facf6a5eb479a95ecc0656f587caf7c..04359987fca92defc591d68320f6f9cee693f9fc 100644
--- a/Source/platform/graphics/gpu/DrawingBuffer.cpp
+++ b/Source/platform/graphics/gpu/DrawingBuffer.cpp
@@ -42,20 +42,26 @@
#include "public/platform/WebExternalTextureLayer.h"
#include "public/platform/WebGraphicsContext3D.h"
#include "public/platform/WebGraphicsContext3DProvider.h"
+#ifndef NDEBUG
+#include "wtf/RefCountedLeakCounter.h"
+#endif
using namespace std;
namespace WebCore {
+namespace {
// Global resource ceiling (expressed in terms of pixels) for DrawingBuffer creation and resize.
// When this limit is set, DrawingBuffer::create() and DrawingBuffer::reset() calls that would
// exceed the global cap will instead clear the buffer.
-static const int s_maximumResourceUsePixels = 16 * 1024 * 1024;
-static int s_currentResourceUsePixels = 0;
-static const float s_resourceAdjustedRatio = 0.5;
+const int s_maximumResourceUsePixels = 16 * 1024 * 1024;
+int s_currentResourceUsePixels = 0;
+const float s_resourceAdjustedRatio = 0.5;
+
+const bool s_allowContextEvictionOnCreate = true;
+const int s_maxScaleAttempts = 3;
-static const bool s_allowContextEvictionOnCreate = true;
-static const int s_maxScaleAttempts = 3;
+DEFINE_DEBUG_ONLY_GLOBAL(WTF::RefCountedLeakCounter, drawingBufferCounter, ("DrawingBuffer"));
class ScopedTextureUnit0BindingRestorer {
public:
@@ -78,6 +84,13 @@ private:
Platform3DObject m_oldTextureUnitZeroId;
};
+inline bool operator==(const blink::WebExternalTextureMailbox& a, const blink::WebExternalTextureMailbox& b)
Ken Russell (switch to Gerrit) 2014/04/20 00:27:41 This really belongs in public/platform/WebExternal
+{
+ return !memcmp(a.name, b.name, sizeof(a.name));
+}
+
+} // namespace
+
PassRefPtr<DrawingBuffer> DrawingBuffer::create(PassOwnPtr<blink::WebGraphicsContext3D> context, const IntSize& size, PreserveDrawingBuffer preserve, PassRefPtr<ContextEvictionManager> contextEvictionManager)
{
ASSERT(context);
@@ -93,8 +106,10 @@ PassRefPtr<DrawingBuffer> DrawingBuffer::create(PassOwnPtr<blink::WebGraphicsCon
extensionsUtil.ensureExtensionEnabled("GL_OES_packed_depth_stencil");
RefPtr<DrawingBuffer> drawingBuffer = adoptRef(new DrawingBuffer(context, multisampleSupported, packedDepthStencilSupported, preserve, contextEvictionManager));
- if (!drawingBuffer->initialize(size))
+ if (!drawingBuffer->initialize(size)) {
+ drawingBuffer->beginDestruction();
return PassRefPtr<DrawingBuffer>();
+ }
return drawingBuffer.release();
}
@@ -130,15 +145,25 @@ DrawingBuffer::DrawingBuffer(PassOwnPtr<blink::WebGraphicsContext3D> context,
, m_maxTextureSize(0)
, m_sampleCount(0)
, m_packAlignment(4)
+ , m_destructionInProgress(false)
, m_contextEvictionManager(contextEvictionManager)
{
// Used by browser tests to detect the use of a DrawingBuffer.
TRACE_EVENT_INSTANT0("test_gpu", "DrawingBufferCreation");
+#ifndef NDEBUG
+ drawingBufferCounter.increment();
+#endif
}
DrawingBuffer::~DrawingBuffer()
{
- releaseResources();
+ ASSERT(m_destructionInProgress);
+ ASSERT(m_textureMailboxes.isEmpty());
+ m_layer.clear();
+ m_context.clear();
+#ifndef NDEBUG
+ drawingBufferCounter.decrement();
+#endif
}
void DrawingBuffer::markContentsChanged()
@@ -165,6 +190,9 @@ blink::WebGraphicsContext3D* DrawingBuffer::context()
bool DrawingBuffer::prepareMailbox(blink::WebExternalTextureMailbox* outMailbox, blink::WebExternalBitmap* bitmap)
{
+ // prepareMailbox() is always called after layout.
+ ASSERT(!m_destructionInProgress);
+
if (!m_contentsChanged)
return false;
@@ -229,6 +257,9 @@ bool DrawingBuffer::prepareMailbox(blink::WebExternalTextureMailbox* outMailbox,
frontColorBufferMailbox->mailbox.syncPoint = m_context->insertSyncPoint();
markLayerComposited();
+ // set m_parentDrawingBuffer to make sure 'this' stays alive as long as it has live mailboxes
+ ASSERT(!frontColorBufferMailbox->m_parentDrawingBuffer);
+ frontColorBufferMailbox->m_parentDrawingBuffer = this;
*outMailbox = frontColorBufferMailbox->mailbox;
m_frontColorBuffer = frontColorBufferMailbox->textureId;
return true;
@@ -236,24 +267,47 @@ bool DrawingBuffer::prepareMailbox(blink::WebExternalTextureMailbox* outMailbox,
void DrawingBuffer::mailboxReleased(const blink::WebExternalTextureMailbox& mailbox)
{
+ if (m_destructionInProgress) {
+ mailboxReleasedWhileDestructionInProgress(mailbox);
+ return;
+ }
+
for (size_t i = 0; i < m_textureMailboxes.size(); i++) {
RefPtr<MailboxInfo> mailboxInfo = m_textureMailboxes[i];
- if (!memcmp(mailboxInfo->mailbox.name, mailbox.name, sizeof(mailbox.name))) {
+ if (mailboxInfo->mailbox == mailbox) {
mailboxInfo->mailbox.syncPoint = mailbox.syncPoint;
- m_recycledMailboxes.prepend(mailboxInfo.release());
+ ASSERT(mailboxInfo->m_parentDrawingBuffer.get() == this);
+ mailboxInfo->m_parentDrawingBuffer.clear();
+ m_recycledMailboxQueue.prepend(mailboxInfo->mailbox);
return;
}
}
ASSERT_NOT_REACHED();
}
+void DrawingBuffer::mailboxReleasedWhileDestructionInProgress(const blink::WebExternalTextureMailbox& mailbox)
+{
+ ASSERT(m_textureMailboxes.size());
+ m_context->makeContextCurrent();
+ // Ensure not to call the destructor until deleteMailbox() is completed.
+ RefPtr<DrawingBuffer> self = this;
+ deleteMailbox(mailbox);
+}
+
PassRefPtr<DrawingBuffer::MailboxInfo> DrawingBuffer::recycledMailbox()
{
- if (m_recycledMailboxes.isEmpty())
+ if (m_recycledMailboxQueue.isEmpty())
return PassRefPtr<MailboxInfo>();
- RefPtr<MailboxInfo> mailboxInfo = m_recycledMailboxes.last().release();
- m_recycledMailboxes.removeLast();
+ blink::WebExternalTextureMailbox mailbox = m_recycledMailboxQueue.takeLast();
+ RefPtr<MailboxInfo> mailboxInfo;
+ for (size_t i = 0; i < m_textureMailboxes.size(); i++) {
+ if (m_textureMailboxes[i]->mailbox == mailbox) {
+ mailboxInfo = m_textureMailboxes[i];
+ break;
+ }
+ }
+ ASSERT(mailboxInfo);
if (mailboxInfo->mailbox.syncPoint) {
m_context->waitSyncPoint(mailboxInfo->mailbox.syncPoint);
@@ -279,6 +333,18 @@ PassRefPtr<DrawingBuffer::MailboxInfo> DrawingBuffer::createNewMailbox(unsigned
return returnMailbox.release();
}
+void DrawingBuffer::deleteMailbox(const blink::WebExternalTextureMailbox& mailbox)
+{
+ for (size_t i = 0; i < m_textureMailboxes.size(); i++) {
+ if (m_textureMailboxes[i]->mailbox == mailbox) {
+ m_context->deleteTexture(m_textureMailboxes[i]->textureId);
+ m_textureMailboxes.remove(i);
+ return;
+ }
+ }
+ ASSERT_NOT_REACHED();
+}
+
bool DrawingBuffer::initialize(const IntSize& size)
{
m_attributes = m_context->getContextAttributes();
@@ -473,14 +539,17 @@ void DrawingBuffer::clearPlatformLayer()
m_context->flush();
}
-void DrawingBuffer::releaseResources()
+void DrawingBuffer::beginDestruction()
{
+ ASSERT(!m_destructionInProgress);
+ m_destructionInProgress = true;
+
m_context->makeContextCurrent();
clearPlatformLayer();
- for (size_t i = 0; i < m_textureMailboxes.size(); i++)
- m_context->deleteTexture(m_textureMailboxes[i]->textureId);
+ while (!m_recycledMailboxQueue.isEmpty())
+ deleteMailbox(m_recycledMailboxQueue.takeLast());
dshwang 2014/04/19 00:58:06 now m_recycledMailboxQueue just keeps mailbox name
if (m_multisampleFBO)
m_context->deleteFramebuffer(m_multisampleFBO);
@@ -503,8 +572,6 @@ void DrawingBuffer::releaseResources()
if (m_colorBuffer)
m_context->deleteTexture(m_colorBuffer);
- m_context.clear();
-
setSize(IntSize());
m_colorBuffer = 0;
@@ -517,13 +584,8 @@ void DrawingBuffer::releaseResources()
m_fbo = 0;
m_contextEvictionManager.clear();
- m_recycledMailboxes.clear();
- m_textureMailboxes.clear();
-
- if (m_layer) {
+ if (m_layer)
GraphicsLayer::unregisterContentsLayer(m_layer->layer());
- m_layer.clear();
- }
}
unsigned DrawingBuffer::createColorTexture(const IntSize& size)
« no previous file with comments | « Source/platform/graphics/gpu/DrawingBuffer.h ('k') | Source/platform/graphics/gpu/DrawingBufferTest.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698