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

Side by Side Diff: third_party/WebKit/Source/platform/graphics/gpu/DrawingBuffer.cpp

Issue 2407753002: Fix crash from state management cleanup (Closed)
Patch Set: Fix state restore missed Created 4 years, 2 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 unified diff | Download patch
OLDNEW
1 /* 1 /*
2 * Copyright (c) 2010, Google Inc. All rights reserved. 2 * Copyright (c) 2010, Google Inc. All rights reserved.
3 * 3 *
4 * Redistribution and use in source and binary forms, with or without 4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are 5 * modification, are permitted provided that the following conditions are
6 * met: 6 * met:
7 * 7 *
8 * * Redistributions of source code must retain the above copyright 8 * * Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer. 9 * notice, this list of conditions and the following disclaimer.
10 * * Redistributions in binary form must reproduce the above 10 * * Redistributions in binary form must reproduce the above
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
53 #include "wtf/typed_arrays/ArrayBufferContents.h" 53 #include "wtf/typed_arrays/ArrayBufferContents.h"
54 #include <algorithm> 54 #include <algorithm>
55 #include <memory> 55 #include <memory>
56 56
57 namespace blink { 57 namespace blink {
58 58
59 namespace { 59 namespace {
60 60
61 const float s_resourceAdjustedRatio = 0.5; 61 const float s_resourceAdjustedRatio = 0.5;
62 62
63 class ScopedTextureUnit0BindingRestorer {
64 STACK_ALLOCATED();
65 WTF_MAKE_NONCOPYABLE(ScopedTextureUnit0BindingRestorer);
66
67 public:
68 ScopedTextureUnit0BindingRestorer(gpu::gles2::GLES2Interface* gl,
69 GLenum activeTextureUnit,
70 GLuint textureUnitZeroId)
71 : m_gl(gl),
72 m_oldActiveTextureUnit(activeTextureUnit),
73 m_oldTextureUnitZeroId(textureUnitZeroId) {
74 m_gl->ActiveTexture(GL_TEXTURE0);
75 }
76 ~ScopedTextureUnit0BindingRestorer() {
77 m_gl->BindTexture(GL_TEXTURE_2D, m_oldTextureUnitZeroId);
78 m_gl->ActiveTexture(m_oldActiveTextureUnit);
79 }
80
81 private:
82 gpu::gles2::GLES2Interface* m_gl;
83 GLenum m_oldActiveTextureUnit;
84 GLuint m_oldTextureUnitZeroId;
85 };
86
87 static bool shouldFailDrawingBufferCreationForTesting = false; 63 static bool shouldFailDrawingBufferCreationForTesting = false;
88 64
89 } // namespace 65 } // namespace
90 66
91 PassRefPtr<DrawingBuffer> DrawingBuffer::create( 67 PassRefPtr<DrawingBuffer> DrawingBuffer::create(
92 std::unique_ptr<WebGraphicsContext3DProvider> contextProvider, 68 std::unique_ptr<WebGraphicsContext3DProvider> contextProvider,
69 Client* client,
93 const IntSize& size, 70 const IntSize& size,
94 bool premultipliedAlpha, 71 bool premultipliedAlpha,
95 bool wantAlphaChannel, 72 bool wantAlphaChannel,
96 bool wantDepthBuffer, 73 bool wantDepthBuffer,
97 bool wantStencilBuffer, 74 bool wantStencilBuffer,
98 bool wantAntialiasing, 75 bool wantAntialiasing,
99 PreserveDrawingBuffer preserve, 76 PreserveDrawingBuffer preserve,
100 WebGLVersion webGLVersion, 77 WebGLVersion webGLVersion,
101 ChromiumImageUsage chromiumImageUsage) { 78 ChromiumImageUsage chromiumImageUsage) {
102 ASSERT(contextProvider); 79 ASSERT(contextProvider);
(...skipping 26 matching lines...) Expand all
129 else 106 else
130 extensionsUtil->ensureExtensionEnabled( 107 extensionsUtil->ensureExtensionEnabled(
131 "GL_EXT_multisampled_render_to_texture"); 108 "GL_EXT_multisampled_render_to_texture");
132 } 109 }
133 bool discardFramebufferSupported = 110 bool discardFramebufferSupported =
134 extensionsUtil->supportsExtension("GL_EXT_discard_framebuffer"); 111 extensionsUtil->supportsExtension("GL_EXT_discard_framebuffer");
135 if (discardFramebufferSupported) 112 if (discardFramebufferSupported)
136 extensionsUtil->ensureExtensionEnabled("GL_EXT_discard_framebuffer"); 113 extensionsUtil->ensureExtensionEnabled("GL_EXT_discard_framebuffer");
137 114
138 RefPtr<DrawingBuffer> drawingBuffer = adoptRef(new DrawingBuffer( 115 RefPtr<DrawingBuffer> drawingBuffer = adoptRef(new DrawingBuffer(
139 std::move(contextProvider), std::move(extensionsUtil), 116 std::move(contextProvider), std::move(extensionsUtil), client,
140 discardFramebufferSupported, wantAlphaChannel, premultipliedAlpha, 117 discardFramebufferSupported, wantAlphaChannel, premultipliedAlpha,
141 preserve, webGLVersion, wantDepthBuffer, wantStencilBuffer, 118 preserve, webGLVersion, wantDepthBuffer, wantStencilBuffer,
142 chromiumImageUsage)); 119 chromiumImageUsage));
143 if (!drawingBuffer->initialize(size, multisampleSupported)) { 120 if (!drawingBuffer->initialize(size, multisampleSupported)) {
144 drawingBuffer->beginDestruction(); 121 drawingBuffer->beginDestruction();
145 return PassRefPtr<DrawingBuffer>(); 122 return PassRefPtr<DrawingBuffer>();
146 } 123 }
147 return drawingBuffer.release(); 124 return drawingBuffer.release();
148 } 125 }
149 126
150 void DrawingBuffer::forceNextDrawingBufferCreationToFail() { 127 void DrawingBuffer::forceNextDrawingBufferCreationToFail() {
151 shouldFailDrawingBufferCreationForTesting = true; 128 shouldFailDrawingBufferCreationForTesting = true;
152 } 129 }
153 130
154 DrawingBuffer::DrawingBuffer( 131 DrawingBuffer::DrawingBuffer(
155 std::unique_ptr<WebGraphicsContext3DProvider> contextProvider, 132 std::unique_ptr<WebGraphicsContext3DProvider> contextProvider,
156 std::unique_ptr<Extensions3DUtil> extensionsUtil, 133 std::unique_ptr<Extensions3DUtil> extensionsUtil,
134 Client* client,
157 bool discardFramebufferSupported, 135 bool discardFramebufferSupported,
158 bool wantAlphaChannel, 136 bool wantAlphaChannel,
159 bool premultipliedAlpha, 137 bool premultipliedAlpha,
160 PreserveDrawingBuffer preserve, 138 PreserveDrawingBuffer preserve,
161 WebGLVersion webGLVersion, 139 WebGLVersion webGLVersion,
162 bool wantDepth, 140 bool wantDepth,
163 bool wantStencil, 141 bool wantStencil,
164 ChromiumImageUsage chromiumImageUsage) 142 ChromiumImageUsage chromiumImageUsage)
165 : m_preserveDrawingBuffer(preserve), 143 : m_client(client),
144 m_preserveDrawingBuffer(preserve),
166 m_webGLVersion(webGLVersion), 145 m_webGLVersion(webGLVersion),
167 m_contextProvider(std::move(contextProvider)), 146 m_contextProvider(std::move(contextProvider)),
168 m_gl(m_contextProvider->contextGL()), 147 m_gl(m_contextProvider->contextGL()),
169 m_extensionsUtil(std::move(extensionsUtil)), 148 m_extensionsUtil(std::move(extensionsUtil)),
170 m_discardFramebufferSupported(discardFramebufferSupported), 149 m_discardFramebufferSupported(discardFramebufferSupported),
171 m_wantAlphaChannel(wantAlphaChannel), 150 m_wantAlphaChannel(wantAlphaChannel),
172 m_premultipliedAlpha(premultipliedAlpha), 151 m_premultipliedAlpha(premultipliedAlpha),
173 m_softwareRendering(m_contextProvider->isSoftwareRendering()), 152 m_softwareRendering(m_contextProvider->isSoftwareRendering()),
174 m_wantDepth(wantDepth), 153 m_wantDepth(wantDepth),
175 m_wantStencil(wantStencil), 154 m_wantStencil(wantStencil),
176 m_chromiumImageUsage(chromiumImageUsage) { 155 m_chromiumImageUsage(chromiumImageUsage) {
177 memset(m_colorMask, 0, 4 * sizeof(GLboolean));
178 memset(m_clearColor, 0, 4 * sizeof(GLfloat));
179 // Used by browser tests to detect the use of a DrawingBuffer. 156 // Used by browser tests to detect the use of a DrawingBuffer.
180 TRACE_EVENT_INSTANT0("test_gpu", "DrawingBufferCreation", 157 TRACE_EVENT_INSTANT0("test_gpu", "DrawingBufferCreation",
181 TRACE_EVENT_SCOPE_GLOBAL); 158 TRACE_EVENT_SCOPE_GLOBAL);
182 } 159 }
183 160
184 DrawingBuffer::~DrawingBuffer() { 161 DrawingBuffer::~DrawingBuffer() {
185 DCHECK(m_destructionInProgress); 162 DCHECK(m_destructionInProgress);
186 m_layer.reset(); 163 m_layer.reset();
187 m_contextProvider.reset(); 164 m_contextProvider.reset();
188 } 165 }
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
222 199
223 void DrawingBuffer::setFilterQuality(SkFilterQuality filterQuality) { 200 void DrawingBuffer::setFilterQuality(SkFilterQuality filterQuality) {
224 if (m_filterQuality != filterQuality) { 201 if (m_filterQuality != filterQuality) {
225 m_filterQuality = filterQuality; 202 m_filterQuality = filterQuality;
226 if (m_layer) 203 if (m_layer)
227 m_layer->setNearestNeighbor(filterQuality == kNone_SkFilterQuality); 204 m_layer->setNearestNeighbor(filterQuality == kNone_SkFilterQuality);
228 } 205 }
229 } 206 }
230 207
231 bool DrawingBuffer::requiresAlphaChannelToBePreserved() { 208 bool DrawingBuffer::requiresAlphaChannelToBePreserved() {
232 return !m_drawFramebufferBinding && 209 return m_client->DrawingBufferClientIsBoundForDraw() &&
233 defaultBufferRequiresAlphaChannelToBePreserved(); 210 defaultBufferRequiresAlphaChannelToBePreserved();
234 } 211 }
235 212
236 bool DrawingBuffer::defaultBufferRequiresAlphaChannelToBePreserved() { 213 bool DrawingBuffer::defaultBufferRequiresAlphaChannelToBePreserved() {
237 if (wantExplicitResolve()) { 214 if (wantExplicitResolve()) {
238 return !m_wantAlphaChannel && 215 return !m_wantAlphaChannel &&
239 getMultisampledRenderbufferFormat() == GL_RGBA8_OES; 216 getMultisampledRenderbufferFormat() == GL_RGBA8_OES;
240 } 217 }
241 218
242 bool rgbEmulation = 219 bool rgbEmulation =
(...skipping 15 matching lines...) Expand all
258 DCHECK(recycled.size == m_size); 235 DCHECK(recycled.size == m_size);
259 return std::move(recycled.bitmap); 236 return std::move(recycled.bitmap);
260 } 237 }
261 238
262 return Platform::current()->allocateSharedBitmap(m_size); 239 return Platform::current()->allocateSharedBitmap(m_size);
263 } 240 }
264 241
265 bool DrawingBuffer::PrepareTextureMailbox( 242 bool DrawingBuffer::PrepareTextureMailbox(
266 cc::TextureMailbox* outMailbox, 243 cc::TextureMailbox* outMailbox,
267 std::unique_ptr<cc::SingleReleaseCallback>* outReleaseCallback) { 244 std::unique_ptr<cc::SingleReleaseCallback>* outReleaseCallback) {
245 ScopedStateRestorer scopedStateRestorer(this);
268 bool forceGpuResult = false; 246 bool forceGpuResult = false;
269 return prepareTextureMailboxInternal(outMailbox, outReleaseCallback, 247 return prepareTextureMailboxInternal(outMailbox, outReleaseCallback,
270 forceGpuResult); 248 forceGpuResult);
271 } 249 }
272 250
273 bool DrawingBuffer::prepareTextureMailboxInternal( 251 bool DrawingBuffer::prepareTextureMailboxInternal(
274 cc::TextureMailbox* outMailbox, 252 cc::TextureMailbox* outMailbox,
275 std::unique_ptr<cc::SingleReleaseCallback>* outReleaseCallback, 253 std::unique_ptr<cc::SingleReleaseCallback>* outReleaseCallback,
276 bool forceGpuResult) { 254 bool forceGpuResult) {
277 if (m_destructionInProgress) { 255 if (m_destructionInProgress) {
(...skipping 14 matching lines...) Expand all
292 if (m_gl->GetGraphicsResetStatusKHR() != GL_NO_ERROR) 270 if (m_gl->GetGraphicsResetStatusKHR() != GL_NO_ERROR)
293 return false; 271 return false;
294 272
295 TRACE_EVENT0("blink,rail", "DrawingBuffer::prepareMailbox"); 273 TRACE_EVENT0("blink,rail", "DrawingBuffer::prepareMailbox");
296 274
297 if (m_newMailboxCallback) 275 if (m_newMailboxCallback)
298 (*m_newMailboxCallback)(); 276 (*m_newMailboxCallback)();
299 277
300 // Resolve the multisampled buffer into m_backColorBuffer texture. 278 // Resolve the multisampled buffer into m_backColorBuffer texture.
301 if (m_antiAliasingMode != None) 279 if (m_antiAliasingMode != None)
302 commit(); 280 resolveMultisampleFramebufferInternal();
303 281
304 if (m_softwareRendering && !forceGpuResult) { 282 if (m_softwareRendering && !forceGpuResult) {
305 return finishPrepareTextureMailboxSoftware(outMailbox, outReleaseCallback); 283 return finishPrepareTextureMailboxSoftware(outMailbox, outReleaseCallback);
306 } else { 284 } else {
307 return finishPrepareTextureMailboxGpu(outMailbox, outReleaseCallback); 285 return finishPrepareTextureMailboxGpu(outMailbox, outReleaseCallback);
308 } 286 }
309 } 287 }
310 288
311 bool DrawingBuffer::finishPrepareTextureMailboxSoftware( 289 bool DrawingBuffer::finishPrepareTextureMailboxSoftware(
312 cc::TextureMailbox* outMailbox, 290 cc::TextureMailbox* outMailbox,
(...skipping 24 matching lines...) Expand all
337 WTF::passed(std::move(bitmap)), m_size); 315 WTF::passed(std::move(bitmap)), m_size);
338 *outReleaseCallback = 316 *outReleaseCallback =
339 cc::SingleReleaseCallback::Create(convertToBaseCallback(std::move(func))); 317 cc::SingleReleaseCallback::Create(convertToBaseCallback(std::move(func)));
340 return true; 318 return true;
341 } 319 }
342 320
343 bool DrawingBuffer::finishPrepareTextureMailboxGpu( 321 bool DrawingBuffer::finishPrepareTextureMailboxGpu(
344 cc::TextureMailbox* outMailbox, 322 cc::TextureMailbox* outMailbox,
345 std::unique_ptr<cc::SingleReleaseCallback>* outReleaseCallback) { 323 std::unique_ptr<cc::SingleReleaseCallback>* outReleaseCallback) {
346 if (m_webGLVersion > WebGL1) { 324 if (m_webGLVersion > WebGL1) {
325 m_stateRestorer->setPixelUnpackBufferBindingDirty();
347 m_gl->BindBuffer(GL_PIXEL_UNPACK_BUFFER, 0); 326 m_gl->BindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
348 } 327 }
349 328
350 // We must restore the texture binding since creating new textures,
351 // consuming and producing mailboxes changes it.
352 ScopedTextureUnit0BindingRestorer restorer(m_gl, m_activeTextureUnit,
353 m_texture2DBinding);
354
355 // Specify the buffer that we will put in the mailbox. 329 // Specify the buffer that we will put in the mailbox.
356 RefPtr<ColorBuffer> colorBufferForMailbox; 330 RefPtr<ColorBuffer> colorBufferForMailbox;
357 if (m_preserveDrawingBuffer == Discard) { 331 if (m_preserveDrawingBuffer == Discard) {
358 // If we can discard the backbuffer, send the old backbuffer directly 332 // If we can discard the backbuffer, send the old backbuffer directly
359 // into the mailbox, and allocate (or recycle) a new backbuffer. 333 // into the mailbox, and allocate (or recycle) a new backbuffer.
360 colorBufferForMailbox = m_backColorBuffer; 334 colorBufferForMailbox = m_backColorBuffer;
361 m_backColorBuffer = createOrRecycleColorBuffer(); 335 m_backColorBuffer = createOrRecycleColorBuffer();
362 attachColorBufferToReadFramebuffer(); 336 attachColorBufferToReadFramebuffer();
363 337
364 // Explicitly specify that m_fbo (which is now bound to the just-allocated 338 // Explicitly specify that m_fbo (which is now bound to the just-allocated
365 // m_backColorBuffer) is not initialized, to save GPU memory bandwidth for 339 // m_backColorBuffer) is not initialized, to save GPU memory bandwidth for
366 // tile-based GPU architectures. 340 // tile-based GPU architectures.
367 if (m_discardFramebufferSupported) { 341 if (m_discardFramebufferSupported) {
368 const GLenum attachments[3] = {GL_COLOR_ATTACHMENT0, GL_DEPTH_ATTACHMENT, 342 const GLenum attachments[3] = {GL_COLOR_ATTACHMENT0, GL_DEPTH_ATTACHMENT,
369 GL_STENCIL_ATTACHMENT}; 343 GL_STENCIL_ATTACHMENT};
344 m_stateRestorer->setFramebufferBindingDirty();
370 m_gl->BindFramebuffer(GL_FRAMEBUFFER, m_fbo); 345 m_gl->BindFramebuffer(GL_FRAMEBUFFER, m_fbo);
371 m_gl->DiscardFramebufferEXT(GL_FRAMEBUFFER, 3, attachments); 346 m_gl->DiscardFramebufferEXT(GL_FRAMEBUFFER, 3, attachments);
372 } 347 }
373 } else { 348 } else {
374 // If we can't discard the backbuffer, create (or recycle) a buffer to put 349 // If we can't discard the backbuffer, create (or recycle) a buffer to put
375 // in the mailbox, and copy backbuffer's contents there. 350 // in the mailbox, and copy backbuffer's contents there.
376 colorBufferForMailbox = createOrRecycleColorBuffer(); 351 colorBufferForMailbox = createOrRecycleColorBuffer();
377 m_gl->CopySubTextureCHROMIUM( 352 m_gl->CopySubTextureCHROMIUM(
378 m_backColorBuffer->textureId, colorBufferForMailbox->textureId, 0, 0, 0, 353 m_backColorBuffer->textureId, colorBufferForMailbox->textureId, 0, 0, 0,
379 0, m_size.width(), m_size.height(), GL_FALSE, GL_FALSE, GL_FALSE); 354 0, m_size.width(), m_size.height(), GL_FALSE, GL_FALSE, GL_FALSE);
(...skipping 27 matching lines...) Expand all
407 // mailbox is released (and while the release callback is running). 382 // mailbox is released (and while the release callback is running).
408 auto func = WTF::bind(&DrawingBuffer::mailboxReleasedGpu, 383 auto func = WTF::bind(&DrawingBuffer::mailboxReleasedGpu,
409 RefPtr<DrawingBuffer>(this), colorBufferForMailbox); 384 RefPtr<DrawingBuffer>(this), colorBufferForMailbox);
410 *outReleaseCallback = cc::SingleReleaseCallback::Create( 385 *outReleaseCallback = cc::SingleReleaseCallback::Create(
411 convertToBaseCallback(std::move(func))); 386 convertToBaseCallback(std::move(func)));
412 } 387 }
413 388
414 // Point |m_frontColorBuffer| to the buffer that we are now presenting. 389 // Point |m_frontColorBuffer| to the buffer that we are now presenting.
415 m_frontColorBuffer = colorBufferForMailbox; 390 m_frontColorBuffer = colorBufferForMailbox;
416 391
417 // Restore any state that we may have dirtied, and update dirty bits.
418 restoreFramebufferBindings();
419 restorePixelUnpackBufferBindings();
420 m_contentsChanged = false; 392 m_contentsChanged = false;
421 setBufferClearNeeded(true); 393 setBufferClearNeeded(true);
422 return true; 394 return true;
423 } 395 }
424 396
425 void DrawingBuffer::mailboxReleasedGpu(RefPtr<ColorBuffer> colorBuffer, 397 void DrawingBuffer::mailboxReleasedGpu(RefPtr<ColorBuffer> colorBuffer,
426 const gpu::SyncToken& syncToken, 398 const gpu::SyncToken& syncToken,
427 bool lostResource) { 399 bool lostResource) {
428 // If the mailbox has been returned by the compositor then it is no 400 // If the mailbox has been returned by the compositor then it is no
429 // longer being presented, and so is no longer the front buffer. 401 // longer being presented, and so is no longer the front buffer.
(...skipping 28 matching lines...) Expand all
458 bool lostResource) { 430 bool lostResource) {
459 DCHECK(!syncToken.HasData()); // No sync tokens for software resources. 431 DCHECK(!syncToken.HasData()); // No sync tokens for software resources.
460 if (m_destructionInProgress || lostResource || m_isHidden || size != m_size) 432 if (m_destructionInProgress || lostResource || m_isHidden || size != m_size)
461 return; // Just delete the bitmap. 433 return; // Just delete the bitmap.
462 434
463 RecycledBitmap recycled = {std::move(bitmap), m_size}; 435 RecycledBitmap recycled = {std::move(bitmap), m_size};
464 m_recycledBitmaps.append(std::move(recycled)); 436 m_recycledBitmaps.append(std::move(recycled));
465 } 437 }
466 438
467 PassRefPtr<StaticBitmapImage> DrawingBuffer::transferToStaticBitmapImage() { 439 PassRefPtr<StaticBitmapImage> DrawingBuffer::transferToStaticBitmapImage() {
440 ScopedStateRestorer scopedStateRestorer(this);
441
468 // This can be null if the context is lost before the first call to 442 // This can be null if the context is lost before the first call to
469 // grContext(). 443 // grContext().
470 GrContext* grContext = m_contextProvider->grContext(); 444 GrContext* grContext = m_contextProvider->grContext();
471 445
472 cc::TextureMailbox textureMailbox; 446 cc::TextureMailbox textureMailbox;
473 std::unique_ptr<cc::SingleReleaseCallback> releaseCallback; 447 std::unique_ptr<cc::SingleReleaseCallback> releaseCallback;
474 bool success = false; 448 bool success = false;
475 if (grContext) { 449 if (grContext) {
476 bool forceGpuResult = true; 450 bool forceGpuResult = true;
477 success = prepareTextureMailboxInternal(&textureMailbox, &releaseCallback, 451 success = prepareTextureMailboxInternal(&textureMailbox, &releaseCallback,
(...skipping 133 matching lines...) Expand 10 before | Expand all | Expand 10 after
611 GLuint imageId) 585 GLuint imageId)
612 : drawingBuffer(drawingBuffer), 586 : drawingBuffer(drawingBuffer),
613 parameters(parameters), 587 parameters(parameters),
614 size(size), 588 size(size),
615 textureId(textureId), 589 textureId(textureId),
616 imageId(imageId) { 590 imageId(imageId) {
617 drawingBuffer->contextGL()->GenMailboxCHROMIUM(mailbox.name); 591 drawingBuffer->contextGL()->GenMailboxCHROMIUM(mailbox.name);
618 } 592 }
619 593
620 DrawingBuffer::ColorBuffer::~ColorBuffer() { 594 DrawingBuffer::ColorBuffer::~ColorBuffer() {
621 gpu::gles2::GLES2Interface* gl = drawingBuffer->contextGL(); 595 gpu::gles2::GLES2Interface* gl = drawingBuffer->m_gl;
622 if (receiveSyncToken.HasData()) 596 if (receiveSyncToken.HasData())
623 gl->WaitSyncTokenCHROMIUM(receiveSyncToken.GetConstData()); 597 gl->WaitSyncTokenCHROMIUM(receiveSyncToken.GetConstData());
624 if (imageId) { 598 if (imageId) {
625 gl->BindTexture(parameters.target, textureId); 599 gl->BindTexture(parameters.target, textureId);
626 gl->ReleaseTexImage2DCHROMIUM(parameters.target, imageId); 600 gl->ReleaseTexImage2DCHROMIUM(parameters.target, imageId);
627 gl->DestroyImageCHROMIUM(imageId); 601 gl->DestroyImageCHROMIUM(imageId);
602 switch (parameters.target) {
603 case GL_TEXTURE_2D:
604 // Restore the texture binding for GL_TEXTURE_2D, since the client will
605 // expect the previous state.
606 if (drawingBuffer->m_client)
607 drawingBuffer->m_client->DrawingBufferClientRestoreTexture2DBinding();
608 break;
609 case GC3D_TEXTURE_RECTANGLE_ARB:
610 // Rectangle textures aren't exposed to WebGL, so don't bother
611 // restoring this state (there is no meaningful way to restore it).
612 break;
613 default:
614 NOTREACHED();
615 break;
616 }
628 } 617 }
629 gl->DeleteTextures(1, &textureId); 618 gl->DeleteTextures(1, &textureId);
630 } 619 }
631 620
632 bool DrawingBuffer::initialize(const IntSize& size, bool useMultisampling) { 621 bool DrawingBuffer::initialize(const IntSize& size, bool useMultisampling) {
622 ScopedStateRestorer scopedStateRestorer(this);
623
633 if (m_gl->GetGraphicsResetStatusKHR() != GL_NO_ERROR) { 624 if (m_gl->GetGraphicsResetStatusKHR() != GL_NO_ERROR) {
634 // Need to try to restore the context again later. 625 // Need to try to restore the context again later.
635 return false; 626 return false;
636 } 627 }
637 628
638 m_gl->GetIntegerv(GL_MAX_TEXTURE_SIZE, &m_maxTextureSize); 629 m_gl->GetIntegerv(GL_MAX_TEXTURE_SIZE, &m_maxTextureSize);
639 630
640 int maxSampleCount = 0; 631 int maxSampleCount = 0;
641 m_antiAliasingMode = None; 632 m_antiAliasingMode = None;
642 if (useMultisampling) { 633 if (useMultisampling) {
(...skipping 11 matching lines...) Expand all
654 // The Linux ATI bot fails 645 // The Linux ATI bot fails
655 // WebglConformance.conformance_textures_misc_tex_image_webgl, so use storage 646 // WebglConformance.conformance_textures_misc_tex_image_webgl, so use storage
656 // textures only if ScreenSpaceAntialiasing is enabled, because 647 // textures only if ScreenSpaceAntialiasing is enabled, because
657 // ScreenSpaceAntialiasing is much faster with storage textures. 648 // ScreenSpaceAntialiasing is much faster with storage textures.
658 m_storageTextureSupported = 649 m_storageTextureSupported =
659 (m_webGLVersion > WebGL1 || 650 (m_webGLVersion > WebGL1 ||
660 m_extensionsUtil->supportsExtension("GL_EXT_texture_storage")) && 651 m_extensionsUtil->supportsExtension("GL_EXT_texture_storage")) &&
661 m_antiAliasingMode == ScreenSpaceAntialiasing; 652 m_antiAliasingMode == ScreenSpaceAntialiasing;
662 m_sampleCount = std::min(4, maxSampleCount); 653 m_sampleCount = std::min(4, maxSampleCount);
663 654
655 m_stateRestorer->setFramebufferBindingDirty();
664 m_gl->GenFramebuffers(1, &m_fbo); 656 m_gl->GenFramebuffers(1, &m_fbo);
665 m_gl->BindFramebuffer(GL_FRAMEBUFFER, m_fbo); 657 m_gl->BindFramebuffer(GL_FRAMEBUFFER, m_fbo);
666 if (wantExplicitResolve()) { 658 if (wantExplicitResolve()) {
667 m_gl->GenFramebuffers(1, &m_multisampleFBO); 659 m_gl->GenFramebuffers(1, &m_multisampleFBO);
668 m_gl->BindFramebuffer(GL_FRAMEBUFFER, m_multisampleFBO); 660 m_gl->BindFramebuffer(GL_FRAMEBUFFER, m_multisampleFBO);
669 m_gl->GenRenderbuffers(1, &m_multisampleRenderbuffer); 661 m_gl->GenRenderbuffers(1, &m_multisampleRenderbuffer);
670 } 662 }
671 if (!reset(size)) 663 if (!resizeFramebufferInternal(size))
672 return false; 664 return false;
673 665
674 if (m_depthStencilBuffer) { 666 if (m_depthStencilBuffer) {
675 DCHECK(wantDepthOrStencil()); 667 DCHECK(wantDepthOrStencil());
676 m_hasImplicitStencilBuffer = !m_wantStencil; 668 m_hasImplicitStencilBuffer = !m_wantStencil;
677 } 669 }
678 670
679 if (m_gl->GetGraphicsResetStatusKHR() != GL_NO_ERROR) { 671 if (m_gl->GetGraphicsResetStatusKHR() != GL_NO_ERROR) {
680 // It's possible that the drawing buffer allocation provokes a context loss, 672 // It's possible that the drawing buffer allocation provokes a context loss,
681 // so check again just in case. http://crbug.com/512302 673 // so check again just in case. http://crbug.com/512302
682 return false; 674 return false;
683 } 675 }
684 676
685 return true; 677 return true;
686 } 678 }
687 679
688 bool DrawingBuffer::copyToPlatformTexture(gpu::gles2::GLES2Interface* gl, 680 bool DrawingBuffer::copyToPlatformTexture(gpu::gles2::GLES2Interface* gl,
689 GLuint texture, 681 GLuint texture,
690 GLenum internalFormat, 682 GLenum internalFormat,
691 GLenum destType, 683 GLenum destType,
692 GLint level, 684 GLint level,
693 bool premultiplyAlpha, 685 bool premultiplyAlpha,
694 bool flipY, 686 bool flipY,
695 SourceDrawingBuffer sourceBuffer) { 687 SourceDrawingBuffer sourceBuffer) {
688 ScopedStateRestorer scopedStateRestorer(this);
689
696 if (m_contentsChanged) { 690 if (m_contentsChanged) {
697 if (m_antiAliasingMode != None) { 691 if (m_antiAliasingMode != None)
698 commit(); 692 resolveMultisampleFramebufferInternal();
699 restoreFramebufferBindings();
700 }
701 m_gl->Flush(); 693 m_gl->Flush();
702 } 694 }
703 695
704 // Assume that the destination target is GL_TEXTURE_2D. 696 // Assume that the destination target is GL_TEXTURE_2D.
705 if (!Extensions3DUtil::canUseCopyTextureCHROMIUM( 697 if (!Extensions3DUtil::canUseCopyTextureCHROMIUM(
706 GL_TEXTURE_2D, internalFormat, destType, level)) 698 GL_TEXTURE_2D, internalFormat, destType, level))
707 return false; 699 return false;
708 700
709 // Contexts may be in a different share group. We must transfer the texture 701 // Contexts may be in a different share group. We must transfer the texture
710 // through a mailbox first. 702 // through a mailbox first.
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
746 const GLuint64 fenceSync = gl->InsertFenceSyncCHROMIUM(); 738 const GLuint64 fenceSync = gl->InsertFenceSyncCHROMIUM();
747 739
748 gl->Flush(); 740 gl->Flush();
749 gpu::SyncToken syncToken; 741 gpu::SyncToken syncToken;
750 gl->GenSyncTokenCHROMIUM(fenceSync, syncToken.GetData()); 742 gl->GenSyncTokenCHROMIUM(fenceSync, syncToken.GetData());
751 m_gl->WaitSyncTokenCHROMIUM(syncToken.GetData()); 743 m_gl->WaitSyncTokenCHROMIUM(syncToken.GetData());
752 744
753 return true; 745 return true;
754 } 746 }
755 747
756 GLuint DrawingBuffer::framebuffer() const {
757 return m_fbo;
758 }
759
760 WebLayer* DrawingBuffer::platformLayer() { 748 WebLayer* DrawingBuffer::platformLayer() {
761 if (!m_layer) { 749 if (!m_layer) {
762 m_layer = wrapUnique( 750 m_layer = wrapUnique(
763 Platform::current()->compositorSupport()->createExternalTextureLayer( 751 Platform::current()->compositorSupport()->createExternalTextureLayer(
764 this)); 752 this));
765 753
766 m_layer->setOpaque(!m_wantAlphaChannel); 754 m_layer->setOpaque(!m_wantAlphaChannel);
767 m_layer->setBlendBackgroundColor(m_wantAlphaChannel); 755 m_layer->setBlendBackgroundColor(m_wantAlphaChannel);
768 m_layer->setPremultipliedAlpha(m_premultipliedAlpha); 756 m_layer->setPremultipliedAlpha(m_premultipliedAlpha);
769 m_layer->setNearestNeighbor(m_filterQuality == kNone_SkFilterQuality); 757 m_layer->setNearestNeighbor(m_filterQuality == kNone_SkFilterQuality);
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
803 791
804 m_backColorBuffer = nullptr; 792 m_backColorBuffer = nullptr;
805 m_frontColorBuffer = nullptr; 793 m_frontColorBuffer = nullptr;
806 m_multisampleRenderbuffer = 0; 794 m_multisampleRenderbuffer = 0;
807 m_depthStencilBuffer = 0; 795 m_depthStencilBuffer = 0;
808 m_multisampleFBO = 0; 796 m_multisampleFBO = 0;
809 m_fbo = 0; 797 m_fbo = 0;
810 798
811 if (m_layer) 799 if (m_layer)
812 GraphicsLayer::unregisterContentsLayer(m_layer->layer()); 800 GraphicsLayer::unregisterContentsLayer(m_layer->layer());
801
802 m_client = nullptr;
813 } 803 }
814 804
815 bool DrawingBuffer::resizeDefaultFramebuffer(const IntSize& size) { 805 bool DrawingBuffer::resizeDefaultFramebuffer(const IntSize& size) {
816 // Recreate m_backColorBuffer. 806 // Recreate m_backColorBuffer.
817 m_backColorBuffer = createColorBuffer(size); 807 m_backColorBuffer = createColorBuffer(size);
818 808
819 attachColorBufferToReadFramebuffer(); 809 attachColorBufferToReadFramebuffer();
820 810
821 if (wantExplicitResolve()) { 811 if (wantExplicitResolve()) {
812 m_stateRestorer->setFramebufferBindingDirty();
813 m_stateRestorer->setRenderbufferBindingDirty();
822 m_gl->BindFramebuffer(GL_FRAMEBUFFER, m_multisampleFBO); 814 m_gl->BindFramebuffer(GL_FRAMEBUFFER, m_multisampleFBO);
823 m_gl->BindRenderbuffer(GL_RENDERBUFFER, m_multisampleRenderbuffer); 815 m_gl->BindRenderbuffer(GL_RENDERBUFFER, m_multisampleRenderbuffer);
824 m_gl->RenderbufferStorageMultisampleCHROMIUM( 816 m_gl->RenderbufferStorageMultisampleCHROMIUM(
825 GL_RENDERBUFFER, m_sampleCount, getMultisampledRenderbufferFormat(), 817 GL_RENDERBUFFER, m_sampleCount, getMultisampledRenderbufferFormat(),
826 size.width(), size.height()); 818 size.width(), size.height());
827 819
828 if (m_gl->GetError() == GL_OUT_OF_MEMORY) 820 if (m_gl->GetError() == GL_OUT_OF_MEMORY)
829 return false; 821 return false;
830 822
831 m_gl->FramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, 823 m_gl->FramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
832 GL_RENDERBUFFER, m_multisampleRenderbuffer); 824 GL_RENDERBUFFER, m_multisampleRenderbuffer);
833 } 825 }
834 826
835 if (wantDepthOrStencil()) { 827 if (wantDepthOrStencil()) {
828 m_stateRestorer->setFramebufferBindingDirty();
829 m_stateRestorer->setRenderbufferBindingDirty();
836 m_gl->BindFramebuffer(GL_FRAMEBUFFER, 830 m_gl->BindFramebuffer(GL_FRAMEBUFFER,
837 m_multisampleFBO ? m_multisampleFBO : m_fbo); 831 m_multisampleFBO ? m_multisampleFBO : m_fbo);
838 if (!m_depthStencilBuffer) 832 if (!m_depthStencilBuffer)
839 m_gl->GenRenderbuffers(1, &m_depthStencilBuffer); 833 m_gl->GenRenderbuffers(1, &m_depthStencilBuffer);
840 m_gl->BindRenderbuffer(GL_RENDERBUFFER, m_depthStencilBuffer); 834 m_gl->BindRenderbuffer(GL_RENDERBUFFER, m_depthStencilBuffer);
841 if (m_antiAliasingMode == MSAAImplicitResolve) { 835 if (m_antiAliasingMode == MSAAImplicitResolve) {
842 m_gl->RenderbufferStorageMultisampleEXT(GL_RENDERBUFFER, m_sampleCount, 836 m_gl->RenderbufferStorageMultisampleEXT(GL_RENDERBUFFER, m_sampleCount,
843 GL_DEPTH24_STENCIL8_OES, 837 GL_DEPTH24_STENCIL8_OES,
844 size.width(), size.height()); 838 size.width(), size.height());
845 } else if (m_antiAliasingMode == MSAAExplicitResolve) { 839 } else if (m_antiAliasingMode == MSAAExplicitResolve) {
846 m_gl->RenderbufferStorageMultisampleCHROMIUM( 840 m_gl->RenderbufferStorageMultisampleCHROMIUM(
847 GL_RENDERBUFFER, m_sampleCount, GL_DEPTH24_STENCIL8_OES, size.width(), 841 GL_RENDERBUFFER, m_sampleCount, GL_DEPTH24_STENCIL8_OES, size.width(),
848 size.height()); 842 size.height());
849 } else { 843 } else {
850 m_gl->RenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8_OES, 844 m_gl->RenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8_OES,
851 size.width(), size.height()); 845 size.width(), size.height());
852 } 846 }
853 // For ES 2.0 contexts DEPTH_STENCIL is not available natively, so we 847 // For ES 2.0 contexts DEPTH_STENCIL is not available natively, so we
854 // emulate 848 // emulate
855 // it at the command buffer level for WebGL contexts. 849 // it at the command buffer level for WebGL contexts.
856 m_gl->FramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, 850 m_gl->FramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT,
857 GL_RENDERBUFFER, m_depthStencilBuffer); 851 GL_RENDERBUFFER, m_depthStencilBuffer);
858 m_gl->BindRenderbuffer(GL_RENDERBUFFER, 0); 852 m_gl->BindRenderbuffer(GL_RENDERBUFFER, 0);
859 } 853 }
860 854
861 if (wantExplicitResolve()) { 855 if (wantExplicitResolve()) {
856 m_stateRestorer->setFramebufferBindingDirty();
862 m_gl->BindFramebuffer(GL_FRAMEBUFFER, m_multisampleFBO); 857 m_gl->BindFramebuffer(GL_FRAMEBUFFER, m_multisampleFBO);
863 if (m_gl->CheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE) 858 if (m_gl->CheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)
864 return false; 859 return false;
865 } 860 }
866 861
862 m_stateRestorer->setFramebufferBindingDirty();
867 m_gl->BindFramebuffer(GL_FRAMEBUFFER, m_fbo); 863 m_gl->BindFramebuffer(GL_FRAMEBUFFER, m_fbo);
868 return m_gl->CheckFramebufferStatus(GL_FRAMEBUFFER) == 864 return m_gl->CheckFramebufferStatus(GL_FRAMEBUFFER) ==
869 GL_FRAMEBUFFER_COMPLETE; 865 GL_FRAMEBUFFER_COMPLETE;
870 } 866 }
871 867
872 void DrawingBuffer::clearFramebuffers(GLbitfield clearMask) { 868 void DrawingBuffer::clearFramebuffers(GLbitfield clearMask) {
869 ScopedStateRestorer scopedStateRestorer(this);
870 clearFramebuffersInternal(clearMask);
871 }
872
873 void DrawingBuffer::clearFramebuffersInternal(GLbitfield clearMask) {
874 m_stateRestorer->setFramebufferBindingDirty();
873 // We will clear the multisample FBO, but we also need to clear the 875 // We will clear the multisample FBO, but we also need to clear the
874 // non-multisampled buffer. 876 // non-multisampled buffer.
875 if (m_multisampleFBO) { 877 if (m_multisampleFBO) {
876 m_gl->BindFramebuffer(GL_FRAMEBUFFER, m_fbo); 878 m_gl->BindFramebuffer(GL_FRAMEBUFFER, m_fbo);
877 m_gl->Clear(GL_COLOR_BUFFER_BIT); 879 m_gl->Clear(GL_COLOR_BUFFER_BIT);
878 } 880 }
879 881
880 m_gl->BindFramebuffer(GL_FRAMEBUFFER, 882 m_gl->BindFramebuffer(GL_FRAMEBUFFER,
881 m_multisampleFBO ? m_multisampleFBO : m_fbo); 883 m_multisampleFBO ? m_multisampleFBO : m_fbo);
882 m_gl->Clear(clearMask); 884 m_gl->Clear(clearMask);
883 } 885 }
884 886
885 IntSize DrawingBuffer::adjustSize(const IntSize& desiredSize, 887 IntSize DrawingBuffer::adjustSize(const IntSize& desiredSize,
886 const IntSize& curSize, 888 const IntSize& curSize,
887 int maxTextureSize) { 889 int maxTextureSize) {
888 IntSize adjustedSize = desiredSize; 890 IntSize adjustedSize = desiredSize;
889 891
890 // Clamp if the desired size is greater than the maximum texture size for the 892 // Clamp if the desired size is greater than the maximum texture size for the
891 // device. 893 // device.
892 if (adjustedSize.height() > maxTextureSize) 894 if (adjustedSize.height() > maxTextureSize)
893 adjustedSize.setHeight(maxTextureSize); 895 adjustedSize.setHeight(maxTextureSize);
894 896
895 if (adjustedSize.width() > maxTextureSize) 897 if (adjustedSize.width() > maxTextureSize)
896 adjustedSize.setWidth(maxTextureSize); 898 adjustedSize.setWidth(maxTextureSize);
897 899
898 return adjustedSize; 900 return adjustedSize;
899 } 901 }
900 902
901 bool DrawingBuffer::reset(const IntSize& newSize) { 903 bool DrawingBuffer::resize(const IntSize& newSize) {
904 ScopedStateRestorer scopedStateRestorer(this);
905 return resizeFramebufferInternal(newSize);
906 }
907
908 bool DrawingBuffer::resizeFramebufferInternal(const IntSize& newSize) {
902 CHECK(!newSize.isEmpty()); 909 CHECK(!newSize.isEmpty());
903 IntSize adjustedSize = adjustSize(newSize, m_size, m_maxTextureSize); 910 IntSize adjustedSize = adjustSize(newSize, m_size, m_maxTextureSize);
904 if (adjustedSize.isEmpty()) 911 if (adjustedSize.isEmpty())
905 return false; 912 return false;
906 913
907 if (adjustedSize != m_size) { 914 if (adjustedSize != m_size) {
908 do { 915 do {
909 if (!resizeDefaultFramebuffer(adjustedSize)) { 916 if (!resizeDefaultFramebuffer(adjustedSize)) {
910 adjustedSize.scale(s_resourceAdjustedRatio); 917 adjustedSize.scale(s_resourceAdjustedRatio);
911 continue; 918 continue;
912 } 919 }
913 break; 920 break;
914 } while (!adjustedSize.isEmpty()); 921 } while (!adjustedSize.isEmpty());
915 922
916 m_size = adjustedSize; 923 m_size = adjustedSize;
917 // Free all mailboxes, because they are now of the wrong size. Only the 924 // Free all mailboxes, because they are now of the wrong size. Only the
918 // first call in this loop has any effect. 925 // first call in this loop has any effect.
919 m_recycledColorBufferQueue.clear(); 926 m_recycledColorBufferQueue.clear();
920 m_recycledBitmaps.clear(); 927 m_recycledBitmaps.clear();
921 928
922 if (adjustedSize.isEmpty()) 929 if (adjustedSize.isEmpty())
923 return false; 930 return false;
924 } 931 }
925 932
933 m_stateRestorer->setClearStateDirty();
926 m_gl->Disable(GL_SCISSOR_TEST); 934 m_gl->Disable(GL_SCISSOR_TEST);
927 m_gl->ClearColor(0, 0, 0, 935 m_gl->ClearColor(0, 0, 0,
928 defaultBufferRequiresAlphaChannelToBePreserved() ? 1 : 0); 936 defaultBufferRequiresAlphaChannelToBePreserved() ? 1 : 0);
929 m_gl->ColorMask(true, true, true, true); 937 m_gl->ColorMask(true, true, true, true);
930 938
931 GLbitfield clearMask = GL_COLOR_BUFFER_BIT; 939 GLbitfield clearMask = GL_COLOR_BUFFER_BIT;
932 if (!!m_depthStencilBuffer) { 940 if (!!m_depthStencilBuffer) {
933 m_gl->ClearDepthf(1.0f); 941 m_gl->ClearDepthf(1.0f);
934 clearMask |= GL_DEPTH_BUFFER_BIT; 942 clearMask |= GL_DEPTH_BUFFER_BIT;
935 m_gl->DepthMask(true); 943 m_gl->DepthMask(true);
936 } 944 }
937 if (!!m_depthStencilBuffer) { 945 if (!!m_depthStencilBuffer) {
938 m_gl->ClearStencil(0); 946 m_gl->ClearStencil(0);
939 clearMask |= GL_STENCIL_BUFFER_BIT; 947 clearMask |= GL_STENCIL_BUFFER_BIT;
940 m_gl->StencilMaskSeparate(GL_FRONT, 0xFFFFFFFF); 948 m_gl->StencilMaskSeparate(GL_FRONT, 0xFFFFFFFF);
941 } 949 }
942 950
943 clearFramebuffers(clearMask); 951 clearFramebuffersInternal(clearMask);
944 return true; 952 return true;
945 } 953 }
946 954
947 void DrawingBuffer::commit() { 955 void DrawingBuffer::resolveAndBindForReadAndDraw() {
956 {
957 ScopedStateRestorer scopedStateRestorer(this);
958 resolveMultisampleFramebufferInternal();
959 }
960 m_gl->BindFramebuffer(GL_FRAMEBUFFER, m_fbo);
961 }
962
963 void DrawingBuffer::resolveMultisampleFramebufferInternal() {
964 m_stateRestorer->setFramebufferBindingDirty();
948 if (wantExplicitResolve() && !m_contentsChangeCommitted) { 965 if (wantExplicitResolve() && !m_contentsChangeCommitted) {
966 m_stateRestorer->setClearStateDirty();
949 m_gl->BindFramebuffer(GL_READ_FRAMEBUFFER_ANGLE, m_multisampleFBO); 967 m_gl->BindFramebuffer(GL_READ_FRAMEBUFFER_ANGLE, m_multisampleFBO);
950 m_gl->BindFramebuffer(GL_DRAW_FRAMEBUFFER_ANGLE, m_fbo); 968 m_gl->BindFramebuffer(GL_DRAW_FRAMEBUFFER_ANGLE, m_fbo);
951 969 m_gl->Disable(GL_SCISSOR_TEST);
952 if (m_scissorEnabled)
953 m_gl->Disable(GL_SCISSOR_TEST);
954 970
955 int width = m_size.width(); 971 int width = m_size.width();
956 int height = m_size.height(); 972 int height = m_size.height();
957 // Use NEAREST, because there is no scale performed during the blit. 973 // Use NEAREST, because there is no scale performed during the blit.
958 GLuint filter = GL_NEAREST; 974 GLuint filter = GL_NEAREST;
959 975
960 m_gl->BlitFramebufferCHROMIUM(0, 0, width, height, 0, 0, width, height, 976 m_gl->BlitFramebufferCHROMIUM(0, 0, width, height, 0, 0, width, height,
961 GL_COLOR_BUFFER_BIT, filter); 977 GL_COLOR_BUFFER_BIT, filter);
962 978
963 // On old AMD GPUs on OS X, glColorMask doesn't work correctly for 979 // On old AMD GPUs on OS X, glColorMask doesn't work correctly for
964 // multisampled renderbuffers and the alpha channel can be overwritten. 980 // multisampled renderbuffers and the alpha channel can be overwritten.
965 // Clear the alpha channel of |m_fbo|. 981 // Clear the alpha channel of |m_fbo|.
966 if (defaultBufferRequiresAlphaChannelToBePreserved() && 982 if (defaultBufferRequiresAlphaChannelToBePreserved() &&
967 contextProvider() 983 contextProvider()
968 ->getCapabilities() 984 ->getCapabilities()
969 .disable_multisampling_color_mask_usage) { 985 .disable_multisampling_color_mask_usage) {
970 m_gl->ClearColor(0, 0, 0, 1); 986 m_gl->ClearColor(0, 0, 0, 1);
971 m_gl->ColorMask(false, false, false, true); 987 m_gl->ColorMask(false, false, false, true);
972 m_gl->Clear(GL_COLOR_BUFFER_BIT);
973
974 m_gl->ClearColor(m_clearColor[0], m_clearColor[1], m_clearColor[2],
975 m_clearColor[3]);
976 m_gl->ColorMask(m_colorMask[0], m_colorMask[1], m_colorMask[2],
977 m_colorMask[3]);
978 } 988 }
979
980 if (m_scissorEnabled)
981 m_gl->Enable(GL_SCISSOR_TEST);
982 } 989 }
983 990
984 m_gl->BindFramebuffer(GL_FRAMEBUFFER, m_fbo); 991 m_gl->BindFramebuffer(GL_FRAMEBUFFER, m_fbo);
985 if (m_antiAliasingMode == ScreenSpaceAntialiasing) { 992 if (m_antiAliasingMode == ScreenSpaceAntialiasing)
986 m_gl->ApplyScreenSpaceAntialiasingCHROMIUM(); 993 m_gl->ApplyScreenSpaceAntialiasingCHROMIUM();
987 }
988 m_contentsChangeCommitted = true; 994 m_contentsChangeCommitted = true;
989 } 995 }
990 996
991 void DrawingBuffer::restorePixelUnpackBufferBindings() {
992 if (m_webGLVersion > WebGL1) {
993 m_gl->BindBuffer(GL_PIXEL_UNPACK_BUFFER, m_pixelUnpackBufferBinding);
994 }
995 }
996
997 void DrawingBuffer::restoreFramebufferBindings() { 997 void DrawingBuffer::restoreFramebufferBindings() {
998 if (m_drawFramebufferBinding && m_readFramebufferBinding) { 998 m_client->DrawingBufferClientRestoreFramebufferBinding();
999 if (m_drawFramebufferBinding == m_readFramebufferBinding) {
1000 m_gl->BindFramebuffer(GL_FRAMEBUFFER, m_readFramebufferBinding);
1001 } else {
1002 m_gl->BindFramebuffer(GL_READ_FRAMEBUFFER, m_readFramebufferBinding);
1003 m_gl->BindFramebuffer(GL_DRAW_FRAMEBUFFER, m_drawFramebufferBinding);
1004 }
1005 return;
1006 }
1007 if (!m_drawFramebufferBinding && !m_readFramebufferBinding) {
1008 bind(GL_FRAMEBUFFER);
1009 return;
1010 }
1011 if (!m_drawFramebufferBinding) {
1012 bind(GL_DRAW_FRAMEBUFFER);
1013 m_gl->BindFramebuffer(GL_READ_FRAMEBUFFER, m_readFramebufferBinding);
1014 } else {
1015 bind(GL_READ_FRAMEBUFFER);
1016 m_gl->BindFramebuffer(GL_DRAW_FRAMEBUFFER, m_drawFramebufferBinding);
1017 }
1018 } 999 }
1019 1000
1020 bool DrawingBuffer::multisample() const { 1001 bool DrawingBuffer::multisample() const {
1021 return m_antiAliasingMode != None; 1002 return m_antiAliasingMode != None;
1022 } 1003 }
1023 1004
1024 void DrawingBuffer::bind(GLenum target) { 1005 void DrawingBuffer::bind(GLenum target) {
1025 m_gl->BindFramebuffer(target, 1006 m_gl->BindFramebuffer(target,
1026 wantExplicitResolve() ? m_multisampleFBO : m_fbo); 1007 wantExplicitResolve() ? m_multisampleFBO : m_fbo);
1027 } 1008 }
1028 1009
1029 void DrawingBuffer::setPackAlignment(GLint param) {
1030 m_packAlignment = param;
1031 }
1032
1033 bool DrawingBuffer::paintRenderingResultsToImageData( 1010 bool DrawingBuffer::paintRenderingResultsToImageData(
1034 int& width, 1011 int& width,
1035 int& height, 1012 int& height,
1036 SourceDrawingBuffer sourceBuffer, 1013 SourceDrawingBuffer sourceBuffer,
1037 WTF::ArrayBufferContents& contents) { 1014 WTF::ArrayBufferContents& contents) {
1015 ScopedStateRestorer scopedStateRestorer(this);
1016
1038 ASSERT(!m_premultipliedAlpha); 1017 ASSERT(!m_premultipliedAlpha);
1039 width = size().width(); 1018 width = size().width();
1040 height = size().height(); 1019 height = size().height();
1041 1020
1042 CheckedNumeric<int> dataSize = 4; 1021 CheckedNumeric<int> dataSize = 4;
1043 dataSize *= width; 1022 dataSize *= width;
1044 dataSize *= height; 1023 dataSize *= height;
1045 if (!dataSize.IsValid()) 1024 if (!dataSize.IsValid())
1046 return false; 1025 return false;
1047 1026
1048 WTF::ArrayBufferContents pixels(width * height, 4, 1027 WTF::ArrayBufferContents pixels(width * height, 4,
1049 WTF::ArrayBufferContents::NotShared, 1028 WTF::ArrayBufferContents::NotShared,
1050 WTF::ArrayBufferContents::DontInitialize); 1029 WTF::ArrayBufferContents::DontInitialize);
1051 1030
1052 GLuint fbo = 0; 1031 GLuint fbo = 0;
1032 m_stateRestorer->setFramebufferBindingDirty();
1053 if (sourceBuffer == FrontBuffer && m_frontColorBuffer) { 1033 if (sourceBuffer == FrontBuffer && m_frontColorBuffer) {
1054 m_gl->GenFramebuffers(1, &fbo); 1034 m_gl->GenFramebuffers(1, &fbo);
1055 m_gl->BindFramebuffer(GL_FRAMEBUFFER, fbo); 1035 m_gl->BindFramebuffer(GL_FRAMEBUFFER, fbo);
1056 m_gl->FramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, 1036 m_gl->FramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
1057 m_frontColorBuffer->parameters.target, 1037 m_frontColorBuffer->parameters.target,
1058 m_frontColorBuffer->textureId, 0); 1038 m_frontColorBuffer->textureId, 0);
1059 } else { 1039 } else {
1060 m_gl->BindFramebuffer(GL_FRAMEBUFFER, framebuffer()); 1040 m_gl->BindFramebuffer(GL_FRAMEBUFFER, m_fbo);
1061 } 1041 }
1062 1042
1063 readBackFramebuffer(static_cast<unsigned char*>(pixels.data()), width, height, 1043 readBackFramebuffer(static_cast<unsigned char*>(pixels.data()), width, height,
1064 ReadbackRGBA, WebGLImageConversion::AlphaDoNothing); 1044 ReadbackRGBA, WebGLImageConversion::AlphaDoNothing);
1065 flipVertically(static_cast<uint8_t*>(pixels.data()), width, height); 1045 flipVertically(static_cast<uint8_t*>(pixels.data()), width, height);
1066 1046
1067 if (fbo) { 1047 if (fbo) {
1068 m_gl->FramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, 1048 m_gl->FramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
1069 m_frontColorBuffer->parameters.target, 0, 0); 1049 m_frontColorBuffer->parameters.target, 0, 0);
1070 m_gl->DeleteFramebuffers(1, &fbo); 1050 m_gl->DeleteFramebuffers(1, &fbo);
1071 } 1051 }
1072 1052
1073 restoreFramebufferBindings();
1074
1075 pixels.transfer(contents); 1053 pixels.transfer(contents);
1076 return true; 1054 return true;
1077 } 1055 }
1078 1056
1079 void DrawingBuffer::readBackFramebuffer(unsigned char* pixels, 1057 void DrawingBuffer::readBackFramebuffer(unsigned char* pixels,
1080 int width, 1058 int width,
1081 int height, 1059 int height,
1082 ReadbackOrder readbackOrder, 1060 ReadbackOrder readbackOrder,
1083 WebGLImageConversion::AlphaOp op) { 1061 WebGLImageConversion::AlphaOp op) {
1084 if (m_packAlignment > 4) 1062 m_stateRestorer->setPixelPackAlignmentDirty();
1085 m_gl->PixelStorei(GL_PACK_ALIGNMENT, 1); 1063 m_gl->PixelStorei(GL_PACK_ALIGNMENT, 1);
1086 m_gl->ReadPixels(0, 0, width, height, GL_RGBA, GL_UNSIGNED_BYTE, pixels); 1064 m_gl->ReadPixels(0, 0, width, height, GL_RGBA, GL_UNSIGNED_BYTE, pixels);
1087 if (m_packAlignment > 4)
1088 m_gl->PixelStorei(GL_PACK_ALIGNMENT, m_packAlignment);
1089 1065
1090 size_t bufferSize = 4 * width * height; 1066 size_t bufferSize = 4 * width * height;
1091 1067
1092 if (readbackOrder == ReadbackSkia) { 1068 if (readbackOrder == ReadbackSkia) {
1093 #if (SK_R32_SHIFT == 16) && !SK_B32_SHIFT 1069 #if (SK_R32_SHIFT == 16) && !SK_B32_SHIFT
1094 // Swizzle red and blue channels to match SkBitmap's byte ordering. 1070 // Swizzle red and blue channels to match SkBitmap's byte ordering.
1095 // TODO(kbr): expose GL_BGRA as extension. 1071 // TODO(kbr): expose GL_BGRA as extension.
1096 for (size_t i = 0; i < bufferSize; i += 4) { 1072 for (size_t i = 0; i < bufferSize; i += 4) {
1097 std::swap(pixels[i], pixels[i + 2]); 1073 std::swap(pixels[i], pixels[i + 2]);
1098 } 1074 }
(...skipping 21 matching lines...) Expand all
1120 uint8_t* rowA = framebuffer + i * rowBytes; 1096 uint8_t* rowA = framebuffer + i * rowBytes;
1121 uint8_t* rowB = framebuffer + (height - i - 1) * rowBytes; 1097 uint8_t* rowB = framebuffer + (height - i - 1) * rowBytes;
1122 memcpy(scanline.data(), rowB, rowBytes); 1098 memcpy(scanline.data(), rowB, rowBytes);
1123 memcpy(rowB, rowA, rowBytes); 1099 memcpy(rowB, rowA, rowBytes);
1124 memcpy(rowA, scanline.data(), rowBytes); 1100 memcpy(rowA, scanline.data(), rowBytes);
1125 } 1101 }
1126 } 1102 }
1127 1103
1128 RefPtr<DrawingBuffer::ColorBuffer> DrawingBuffer::createColorBuffer( 1104 RefPtr<DrawingBuffer::ColorBuffer> DrawingBuffer::createColorBuffer(
1129 const IntSize& size) { 1105 const IntSize& size) {
1106 m_stateRestorer->setFramebufferBindingDirty();
1107 m_stateRestorer->setTextureBindingDirty();
1108
1130 // Select the Parameters for the texture object. Allocate the backing 1109 // Select the Parameters for the texture object. Allocate the backing
1131 // GpuMemoryBuffer and GLImage, if one is going to be used. 1110 // GpuMemoryBuffer and GLImage, if one is going to be used.
1132 ColorBufferParameters parameters; 1111 ColorBufferParameters parameters;
1133 GLuint imageId = 0; 1112 GLuint imageId = 0;
1134 if (shouldUseChromiumImage()) { 1113 if (shouldUseChromiumImage()) {
1135 parameters = gpuMemoryBufferColorBufferParameters(); 1114 parameters = gpuMemoryBufferColorBufferParameters();
1136 imageId = m_gl->CreateGpuMemoryBufferImageCHROMIUM( 1115 imageId = m_gl->CreateGpuMemoryBufferImageCHROMIUM(
1137 size.width(), size.height(), parameters.creationInternalColorFormat, 1116 size.width(), size.height(), parameters.creationInternalColorFormat,
1138 GC3D_SCANOUT_CHROMIUM); 1117 GC3D_SCANOUT_CHROMIUM);
1139 } else { 1118 } else {
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
1172 parameters.creationInternalColorFormat, size.width(), 1151 parameters.creationInternalColorFormat, size.width(),
1173 size.height(), 0, parameters.colorFormat, 1152 size.height(), 0, parameters.colorFormat,
1174 GL_UNSIGNED_BYTE, 0); 1153 GL_UNSIGNED_BYTE, 0);
1175 } 1154 }
1176 } 1155 }
1177 1156
1178 // Clear the alpha channel if this is RGB emulated. 1157 // Clear the alpha channel if this is RGB emulated.
1179 if (imageId && !m_wantAlphaChannel && 1158 if (imageId && !m_wantAlphaChannel &&
1180 contextProvider()->getCapabilities().chromium_image_rgb_emulation) { 1159 contextProvider()->getCapabilities().chromium_image_rgb_emulation) {
1181 GLuint fbo = 0; 1160 GLuint fbo = 0;
1161
1162 m_stateRestorer->setClearStateDirty();
1182 m_gl->GenFramebuffers(1, &fbo); 1163 m_gl->GenFramebuffers(1, &fbo);
1183 m_gl->BindFramebuffer(GL_FRAMEBUFFER, fbo); 1164 m_gl->BindFramebuffer(GL_FRAMEBUFFER, fbo);
1184 m_gl->FramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, 1165 m_gl->FramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
1185 parameters.target, textureId, 0); 1166 parameters.target, textureId, 0);
1186 m_gl->ClearColor(0, 0, 0, 1); 1167 m_gl->ClearColor(0, 0, 0, 1);
1187 m_gl->ColorMask(false, false, false, true); 1168 m_gl->ColorMask(false, false, false, true);
1188 m_gl->Clear(GL_COLOR_BUFFER_BIT); 1169 m_gl->Clear(GL_COLOR_BUFFER_BIT);
1189 m_gl->FramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, 1170 m_gl->FramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
1190 parameters.target, 0, 0); 1171 parameters.target, 0, 0);
1191 m_gl->DeleteFramebuffers(1, &fbo); 1172 m_gl->DeleteFramebuffers(1, &fbo);
1192 restoreFramebufferBindings();
1193 m_gl->ClearColor(m_clearColor[0], m_clearColor[1], m_clearColor[2],
1194 m_clearColor[3]);
1195 m_gl->ColorMask(m_colorMask[0], m_colorMask[1], m_colorMask[2],
1196 m_colorMask[3]);
1197 } 1173 }
1198 1174
1199 return adoptRef(new ColorBuffer(this, parameters, size, textureId, imageId)); 1175 return adoptRef(new ColorBuffer(this, parameters, size, textureId, imageId));
1200 } 1176 }
1201 1177
1202 void DrawingBuffer::attachColorBufferToReadFramebuffer() { 1178 void DrawingBuffer::attachColorBufferToReadFramebuffer() {
1179 m_stateRestorer->setFramebufferBindingDirty();
1180 m_stateRestorer->setTextureBindingDirty();
1181
1203 m_gl->BindFramebuffer(GL_FRAMEBUFFER, m_fbo); 1182 m_gl->BindFramebuffer(GL_FRAMEBUFFER, m_fbo);
1204 1183
1205 GLenum target = m_backColorBuffer->parameters.target; 1184 GLenum target = m_backColorBuffer->parameters.target;
1206 GLenum id = m_backColorBuffer->textureId; 1185 GLenum id = m_backColorBuffer->textureId;
1207 1186
1208 m_gl->BindTexture(target, id); 1187 m_gl->BindTexture(target, id);
1209 1188
1210 if (m_antiAliasingMode == MSAAImplicitResolve) 1189 if (m_antiAliasingMode == MSAAImplicitResolve)
1211 m_gl->FramebufferTexture2DMultisampleEXT( 1190 m_gl->FramebufferTexture2DMultisampleEXT(
1212 GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, target, id, 0, m_sampleCount); 1191 GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, target, id, 0, m_sampleCount);
1213 else 1192 else
1214 m_gl->FramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, target, id, 1193 m_gl->FramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, target, id,
1215 0); 1194 0);
1216
1217 restoreTextureBindings();
1218 restoreFramebufferBindings();
1219 } 1195 }
1220 1196
1221 bool DrawingBuffer::wantExplicitResolve() { 1197 bool DrawingBuffer::wantExplicitResolve() {
1222 return m_antiAliasingMode == MSAAExplicitResolve; 1198 return m_antiAliasingMode == MSAAExplicitResolve;
1223 } 1199 }
1224 1200
1225 bool DrawingBuffer::wantDepthOrStencil() { 1201 bool DrawingBuffer::wantDepthOrStencil() {
1226 return m_wantDepth || m_wantStencil; 1202 return m_wantDepth || m_wantStencil;
1227 } 1203 }
1228 1204
1229 GLenum DrawingBuffer::getMultisampledRenderbufferFormat() { 1205 GLenum DrawingBuffer::getMultisampledRenderbufferFormat() {
1230 DCHECK(wantExplicitResolve()); 1206 DCHECK(wantExplicitResolve());
1231 if (m_wantAlphaChannel) 1207 if (m_wantAlphaChannel)
1232 return GL_RGBA8_OES; 1208 return GL_RGBA8_OES;
1233 if (shouldUseChromiumImage() && 1209 if (shouldUseChromiumImage() &&
1234 contextProvider()->getCapabilities().chromium_image_rgb_emulation) 1210 contextProvider()->getCapabilities().chromium_image_rgb_emulation)
1235 return GL_RGBA8_OES; 1211 return GL_RGBA8_OES;
1236 if (contextProvider() 1212 if (contextProvider()
1237 ->getCapabilities() 1213 ->getCapabilities()
1238 .disable_webgl_rgb_multisampling_usage) 1214 .disable_webgl_rgb_multisampling_usage)
1239 return GL_RGBA8_OES; 1215 return GL_RGBA8_OES;
1240 return GL_RGB8_OES; 1216 return GL_RGB8_OES;
1241 } 1217 }
1242 1218
1243 void DrawingBuffer::restoreTextureBindings() { 1219 DrawingBuffer::ScopedStateRestorer::ScopedStateRestorer(
1244 // This class potentially modifies the bindings for GL_TEXTURE_2D and 1220 DrawingBuffer* drawingBuffer)
1245 // GL_TEXTURE_RECTANGLE. Only GL_TEXTURE_2D needs to be restored since 1221 : m_drawingBuffer(drawingBuffer) {
1246 // the public interface for WebGL does not support GL_TEXTURE_RECTANGLE. 1222 DCHECK(!m_drawingBuffer->m_stateRestorer);
1247 m_gl->BindTexture(GL_TEXTURE_2D, m_texture2DBinding); 1223 m_drawingBuffer->m_stateRestorer = this;
1224 }
1225
1226 DrawingBuffer::ScopedStateRestorer::~ScopedStateRestorer() {
1227 m_drawingBuffer->m_stateRestorer = nullptr;
1228 Client* client = m_drawingBuffer->m_client;
1229 if (!client)
1230 return;
1231
1232 if (m_clearStateDirty) {
1233 client->DrawingBufferClientRestoreScissorTest();
1234 client->DrawingBufferClientRestoreMaskAndClearValues();
1235 }
1236 if (m_pixelPackAlignmentDirty)
1237 client->DrawingBufferClientRestorePixelPackAlignment();
1238 if (m_textureBindingDirty)
1239 client->DrawingBufferClientRestoreTexture2DBinding();
1240 if (m_renderbufferBindingDirty)
1241 client->DrawingBufferClientRestoreRenderbufferBinding();
1242 if (m_framebufferBindingDirty)
1243 client->DrawingBufferClientRestoreFramebufferBinding();
1244 if (m_pixelUnpackBufferBindingDirty)
1245 client->DrawingBufferClientRestorePixelUnpackBufferBinding();
1248 } 1246 }
1249 1247
1250 bool DrawingBuffer::shouldUseChromiumImage() { 1248 bool DrawingBuffer::shouldUseChromiumImage() {
1251 return RuntimeEnabledFeatures::webGLImageChromiumEnabled() && 1249 return RuntimeEnabledFeatures::webGLImageChromiumEnabled() &&
1252 m_chromiumImageUsage == AllowChromiumImage; 1250 m_chromiumImageUsage == AllowChromiumImage;
1253 } 1251 }
1254 1252
1255 } // namespace blink 1253 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698