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

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

Issue 2401513002: DrawingBuffer cleanup: Merge structures (Closed)
Patch Set: Add DCHECK and rebase 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 164 matching lines...) Expand 10 before | Expand all | Expand 10 after
175 m_wantStencil(wantStencil), 175 m_wantStencil(wantStencil),
176 m_chromiumImageUsage(chromiumImageUsage) { 176 m_chromiumImageUsage(chromiumImageUsage) {
177 memset(m_colorMask, 0, 4 * sizeof(GLboolean)); 177 memset(m_colorMask, 0, 4 * sizeof(GLboolean));
178 memset(m_clearColor, 0, 4 * sizeof(GLfloat)); 178 memset(m_clearColor, 0, 4 * sizeof(GLfloat));
179 // Used by browser tests to detect the use of a DrawingBuffer. 179 // Used by browser tests to detect the use of a DrawingBuffer.
180 TRACE_EVENT_INSTANT0("test_gpu", "DrawingBufferCreation", 180 TRACE_EVENT_INSTANT0("test_gpu", "DrawingBufferCreation",
181 TRACE_EVENT_SCOPE_GLOBAL); 181 TRACE_EVENT_SCOPE_GLOBAL);
182 } 182 }
183 183
184 DrawingBuffer::~DrawingBuffer() { 184 DrawingBuffer::~DrawingBuffer() {
185 ASSERT(m_destructionInProgress); 185 DCHECK(m_destructionInProgress);
186 ASSERT(m_textureMailboxes.isEmpty());
187 m_layer.reset(); 186 m_layer.reset();
188 m_contextProvider.reset(); 187 m_contextProvider.reset();
189 } 188 }
190 189
191 void DrawingBuffer::markContentsChanged() { 190 void DrawingBuffer::markContentsChanged() {
192 m_contentsChanged = true; 191 m_contentsChanged = true;
193 m_contentsChangeCommitted = false; 192 m_contentsChangeCommitted = false;
194 } 193 }
195 194
196 bool DrawingBuffer::bufferClearNeeded() const { 195 bool DrawingBuffer::bufferClearNeeded() const {
(...skipping 13 matching lines...) Expand all
210 } 209 }
211 210
212 WebGraphicsContext3DProvider* DrawingBuffer::contextProvider() { 211 WebGraphicsContext3DProvider* DrawingBuffer::contextProvider() {
213 return m_contextProvider.get(); 212 return m_contextProvider.get();
214 } 213 }
215 214
216 void DrawingBuffer::setIsHidden(bool hidden) { 215 void DrawingBuffer::setIsHidden(bool hidden) {
217 if (m_isHidden == hidden) 216 if (m_isHidden == hidden)
218 return; 217 return;
219 m_isHidden = hidden; 218 m_isHidden = hidden;
220 if (m_isHidden) 219 if (m_isHidden) {
221 freeRecycledMailboxes(); 220 m_recycledMailboxQueue.clear();
221 m_frontColorBuffer = nullptr;
Ken Russell (switch to Gerrit) 2016/10/07 02:49:30 Per my reply on the CL's comments, I'm not sure th
ccameron 2016/10/07 08:12:30 I played around with this a bit, and I think I fou
222 }
222 } 223 }
223 224
224 void DrawingBuffer::setFilterQuality(SkFilterQuality filterQuality) { 225 void DrawingBuffer::setFilterQuality(SkFilterQuality filterQuality) {
225 if (m_filterQuality != filterQuality) { 226 if (m_filterQuality != filterQuality) {
226 m_filterQuality = filterQuality; 227 m_filterQuality = filterQuality;
227 if (m_layer) 228 if (m_layer)
228 m_layer->setNearestNeighbor(filterQuality == kNone_SkFilterQuality); 229 m_layer->setNearestNeighbor(filterQuality == kNone_SkFilterQuality);
229 } 230 }
230 } 231 }
231 232
232 bool DrawingBuffer::requiresAlphaChannelToBePreserved() { 233 bool DrawingBuffer::requiresAlphaChannelToBePreserved() {
233 return !m_drawFramebufferBinding && 234 return !m_drawFramebufferBinding &&
234 defaultBufferRequiresAlphaChannelToBePreserved(); 235 defaultBufferRequiresAlphaChannelToBePreserved();
235 } 236 }
236 237
237 bool DrawingBuffer::defaultBufferRequiresAlphaChannelToBePreserved() { 238 bool DrawingBuffer::defaultBufferRequiresAlphaChannelToBePreserved() {
238 if (wantExplicitResolve()) { 239 if (wantExplicitResolve()) {
239 return !m_wantAlphaChannel && 240 return !m_wantAlphaChannel &&
240 getMultisampledRenderbufferFormat() == GL_RGBA8_OES; 241 getMultisampledRenderbufferFormat() == GL_RGBA8_OES;
241 } 242 }
242 243
243 bool rgbEmulation = 244 bool rgbEmulation =
244 contextProvider()->getCapabilities().emulate_rgb_buffer_with_rgba || 245 contextProvider()->getCapabilities().emulate_rgb_buffer_with_rgba ||
245 (shouldUseChromiumImage() && 246 (shouldUseChromiumImage() &&
246 contextProvider()->getCapabilities().chromium_image_rgb_emulation); 247 contextProvider()->getCapabilities().chromium_image_rgb_emulation);
247 return !m_wantAlphaChannel && rgbEmulation; 248 return !m_wantAlphaChannel && rgbEmulation;
248 } 249 }
249 250
250 void DrawingBuffer::freeRecycledMailboxes() {
251 while (!m_recycledMailboxQueue.isEmpty()) {
252 RefPtr<RecycledMailbox> recycled = m_recycledMailboxQueue.takeLast();
253 deleteMailbox(recycled->mailbox, recycled->syncToken);
254 }
255 }
256
257 std::unique_ptr<cc::SharedBitmap> DrawingBuffer::createOrRecycleBitmap() { 251 std::unique_ptr<cc::SharedBitmap> DrawingBuffer::createOrRecycleBitmap() {
258 auto it = std::remove_if( 252 auto it = std::remove_if(
259 m_recycledBitmaps.begin(), m_recycledBitmaps.end(), 253 m_recycledBitmaps.begin(), m_recycledBitmaps.end(),
260 [this](const RecycledBitmap& bitmap) { return bitmap.size != m_size; }); 254 [this](const RecycledBitmap& bitmap) { return bitmap.size != m_size; });
261 m_recycledBitmaps.shrink(it - m_recycledBitmaps.begin()); 255 m_recycledBitmaps.shrink(it - m_recycledBitmaps.begin());
262 256
263 if (!m_recycledBitmaps.isEmpty()) { 257 if (!m_recycledBitmaps.isEmpty()) {
264 RecycledBitmap recycled = std::move(m_recycledBitmaps.last()); 258 RecycledBitmap recycled = std::move(m_recycledBitmaps.last());
265 m_recycledBitmaps.removeLast(); 259 m_recycledBitmaps.removeLast();
266 DCHECK(recycled.size == m_size); 260 DCHECK(recycled.size == m_size);
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
298 // software frames, until we get a new context, since the compositor will 292 // software frames, until we get a new context, since the compositor will
299 // be trying to get a new context and may change modes. 293 // be trying to get a new context and may change modes.
300 if (m_gl->GetGraphicsResetStatusKHR() != GL_NO_ERROR) 294 if (m_gl->GetGraphicsResetStatusKHR() != GL_NO_ERROR)
301 return false; 295 return false;
302 296
303 TRACE_EVENT0("blink,rail", "DrawingBuffer::prepareMailbox"); 297 TRACE_EVENT0("blink,rail", "DrawingBuffer::prepareMailbox");
304 298
305 if (m_newMailboxCallback) 299 if (m_newMailboxCallback)
306 (*m_newMailboxCallback)(); 300 (*m_newMailboxCallback)();
307 301
308 // Resolve the multisampled buffer into m_colorBuffer texture. 302 // Resolve the multisampled buffer into m_backColorBuffer texture.
309 if (m_antiAliasingMode != None) 303 if (m_antiAliasingMode != None)
310 commit(); 304 commit();
311 305
312 if (m_softwareRendering && !forceGpuResult) { 306 if (m_softwareRendering && !forceGpuResult) {
313 std::unique_ptr<cc::SharedBitmap> bitmap = createOrRecycleBitmap(); 307 std::unique_ptr<cc::SharedBitmap> bitmap = createOrRecycleBitmap();
314 if (!bitmap) 308 if (!bitmap)
315 return false; 309 return false;
316 unsigned char* pixels = bitmap->pixels(); 310 unsigned char* pixels = bitmap->pixels();
317 DCHECK(pixels); 311 DCHECK(pixels);
318 312
(...skipping 20 matching lines...) Expand all
339 if (m_webGLVersion > WebGL1) { 333 if (m_webGLVersion > WebGL1) {
340 m_gl->BindBuffer(GL_PIXEL_UNPACK_BUFFER, 0); 334 m_gl->BindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
341 } 335 }
342 336
343 // We must restore the texture binding since creating new textures, 337 // We must restore the texture binding since creating new textures,
344 // consuming and producing mailboxes changes it. 338 // consuming and producing mailboxes changes it.
345 ScopedTextureUnit0BindingRestorer restorer(m_gl, m_activeTextureUnit, 339 ScopedTextureUnit0BindingRestorer restorer(m_gl, m_activeTextureUnit,
346 m_texture2DBinding); 340 m_texture2DBinding);
347 341
348 // First try to recycle an old buffer. 342 // First try to recycle an old buffer.
349 RefPtr<MailboxInfo> mailboxInfo = takeRecycledMailbox(); 343 RefPtr<ColorBuffer> colorBufferForMailbox = takeRecycledMailbox();
350 344
351 // No buffer available to recycle, create a new one. 345 // No buffer available to recycle, create a new one.
352 if (!mailboxInfo) 346 if (!colorBufferForMailbox)
353 mailboxInfo = createNewMailbox(createTextureAndAllocateMemory(m_size)); 347 colorBufferForMailbox = createTextureAndAllocateMemory(m_size);
354 348
355 if (m_preserveDrawingBuffer == Discard) { 349 if (m_preserveDrawingBuffer == Discard) {
356 std::swap(mailboxInfo->textureInfo, m_colorBuffer); 350 std::swap(colorBufferForMailbox, m_backColorBuffer);
357 attachColorBufferToReadFramebuffer(); 351 attachColorBufferToReadFramebuffer();
358 352
359 if (m_discardFramebufferSupported) { 353 if (m_discardFramebufferSupported) {
360 // Explicitly discard the framebuffer to save GPU memory bandwidth for 354 // Explicitly discard the framebuffer to save GPU memory bandwidth for
361 // tile-based GPU arch. 355 // tile-based GPU arch.
362 const GLenum attachments[3] = {GL_COLOR_ATTACHMENT0, GL_DEPTH_ATTACHMENT, 356 const GLenum attachments[3] = {GL_COLOR_ATTACHMENT0, GL_DEPTH_ATTACHMENT,
363 GL_STENCIL_ATTACHMENT}; 357 GL_STENCIL_ATTACHMENT};
364 m_gl->BindFramebuffer(GL_FRAMEBUFFER, m_fbo); 358 m_gl->BindFramebuffer(GL_FRAMEBUFFER, m_fbo);
365 m_gl->DiscardFramebufferEXT(GL_FRAMEBUFFER, 3, attachments); 359 m_gl->DiscardFramebufferEXT(GL_FRAMEBUFFER, 3, attachments);
366 } 360 }
367 } else { 361 } else {
368 m_gl->CopySubTextureCHROMIUM( 362 m_gl->CopySubTextureCHROMIUM(
369 m_colorBuffer.textureId, mailboxInfo->textureInfo.textureId, 0, 0, 0, 0, 363 m_backColorBuffer->textureId, colorBufferForMailbox->textureId, 0, 0, 0,
370 m_size.width(), m_size.height(), GL_FALSE, GL_FALSE, GL_FALSE); 364 0, m_size.width(), m_size.height(), GL_FALSE, GL_FALSE, GL_FALSE);
371 } 365 }
372 366
373 restoreFramebufferBindings(); 367 restoreFramebufferBindings();
374 restorePixelUnpackBufferBindings(); 368 restorePixelUnpackBufferBindings();
375 m_contentsChanged = false; 369 m_contentsChanged = false;
376 370
377 m_gl->ProduceTextureDirectCHROMIUM(mailboxInfo->textureInfo.textureId, 371 m_gl->ProduceTextureDirectCHROMIUM(colorBufferForMailbox->textureId,
378 mailboxInfo->textureInfo.parameters.target, 372 colorBufferForMailbox->parameters.target,
379 mailboxInfo->mailbox.name); 373 colorBufferForMailbox->mailbox.name);
380 const GLuint64 fenceSync = m_gl->InsertFenceSyncCHROMIUM(); 374 const GLuint64 fenceSync = m_gl->InsertFenceSyncCHROMIUM();
381 #if OS(MACOSX) 375 #if OS(MACOSX)
382 m_gl->DescheduleUntilFinishedCHROMIUM(); 376 m_gl->DescheduleUntilFinishedCHROMIUM();
383 #endif 377 #endif
384 m_gl->Flush(); 378 m_gl->Flush();
385 gpu::SyncToken syncToken; 379 gpu::SyncToken syncToken;
386 m_gl->GenSyncTokenCHROMIUM(fenceSync, syncToken.GetData()); 380 m_gl->GenSyncTokenCHROMIUM(fenceSync, syncToken.GetData());
387 381
388 bool isOverlayCandidate = mailboxInfo->textureInfo.imageId != 0; 382 bool isOverlayCandidate = colorBufferForMailbox->imageId != 0;
389 bool secureOutputOnly = false; 383 bool secureOutputOnly = false;
390 *outMailbox = cc::TextureMailbox(mailboxInfo->mailbox, syncToken, 384 *outMailbox = cc::TextureMailbox(colorBufferForMailbox->mailbox, syncToken,
391 mailboxInfo->textureInfo.parameters.target, 385 colorBufferForMailbox->parameters.target,
392 gfx::Size(m_size.width(), m_size.height()), 386 gfx::Size(m_size.width(), m_size.height()),
393 isOverlayCandidate, secureOutputOnly); 387 isOverlayCandidate, secureOutputOnly);
394 388
395 // This holds a ref on the DrawingBuffer that will keep it alive until the 389 // This holds a ref on the DrawingBuffer that will keep it alive until the
396 // mailbox is released (and while the release callback is running). 390 // mailbox is released (and while the release callback is running).
397 auto func = WTF::bind(&DrawingBuffer::gpuMailboxReleased, 391 auto func = WTF::bind(&DrawingBuffer::gpuMailboxReleased,
398 RefPtr<DrawingBuffer>(this), mailboxInfo->mailbox); 392 RefPtr<DrawingBuffer>(this), colorBufferForMailbox);
399 *outReleaseCallback = 393 *outReleaseCallback =
400 cc::SingleReleaseCallback::Create(convertToBaseCallback(std::move(func))); 394 cc::SingleReleaseCallback::Create(convertToBaseCallback(std::move(func)));
401 395
402 m_frontColorBuffer = {mailboxInfo->mailbox, syncToken, 396 // Point |m_frontColorBuffer| to the buffer that we are presenting, and
403 mailboxInfo->textureInfo}; 397 // update its sync token.
398 colorBufferForMailbox->produceSyncToken = syncToken;
399 m_frontColorBuffer = colorBufferForMailbox;
404 setBufferClearNeeded(true); 400 setBufferClearNeeded(true);
405 return true; 401 return true;
406 } 402 }
407 403
408 void DrawingBuffer::gpuMailboxReleased(const gpu::Mailbox& mailbox, 404 void DrawingBuffer::gpuMailboxReleased(RefPtr<ColorBuffer> colorBuffer,
409 const gpu::SyncToken& syncToken, 405 const gpu::SyncToken& syncToken,
410 bool lostResource) { 406 bool lostResource) {
411 if (m_destructionInProgress || 407 // Update the SyncToken to ensure that we will wait for it even if we
408 // immediately destroy this buffer.
409 colorBuffer->receiveSyncToken = syncToken;
410
411 if (m_destructionInProgress || colorBuffer->size != m_size ||
412 m_gl->GetGraphicsResetStatusKHR() != GL_NO_ERROR || lostResource || 412 m_gl->GetGraphicsResetStatusKHR() != GL_NO_ERROR || lostResource ||
413 m_isHidden) { 413 m_isHidden) {
414 deleteMailbox(mailbox, syncToken);
415 return; 414 return;
416 } 415 }
417 416
418 // Creation of image backed mailboxes is very expensive, so be less 417 // Creation of image backed mailboxes is very expensive, so be less
419 // aggressive about pruning them. Pruning is done in FIFO order. 418 // aggressive about pruning them. Pruning is done in FIFO order.
420 size_t cacheLimit = 1; 419 size_t cacheLimit = 1;
421 if (shouldUseChromiumImage()) 420 if (shouldUseChromiumImage())
422 cacheLimit = 4; 421 cacheLimit = 4;
423 while (m_recycledMailboxQueue.size() >= cacheLimit) { 422 while (m_recycledMailboxQueue.size() >= cacheLimit)
424 RefPtr<RecycledMailbox> recycled = m_recycledMailboxQueue.takeLast(); 423 m_recycledMailboxQueue.takeLast();
425 deleteMailbox(recycled->mailbox, recycled->syncToken);
426 }
427 424
428 RefPtr<MailboxInfo> mailboxInfo; 425 m_recycledMailboxQueue.prepend(colorBuffer);
429 for (size_t i = 0; i < m_textureMailboxes.size(); i++) {
430 if (m_textureMailboxes[i]->mailbox == mailbox) {
431 mailboxInfo = m_textureMailboxes[i];
432 break;
433 }
434 }
435 DCHECK(mailboxInfo);
436 if (mailboxInfo->size != m_size) {
437 deleteMailbox(mailbox, syncToken);
438 return;
439 }
440
441 m_recycledMailboxQueue.prepend(
442 adoptRef(new RecycledMailbox(mailbox, syncToken)));
443 } 426 }
444 427
445 void DrawingBuffer::softwareMailboxReleased( 428 void DrawingBuffer::softwareMailboxReleased(
446 std::unique_ptr<cc::SharedBitmap> bitmap, 429 std::unique_ptr<cc::SharedBitmap> bitmap,
447 const IntSize& size, 430 const IntSize& size,
448 const gpu::SyncToken& syncToken, 431 const gpu::SyncToken& syncToken,
449 bool lostResource) { 432 bool lostResource) {
450 DCHECK(!syncToken.HasData()); // No sync tokens for software resources. 433 DCHECK(!syncToken.HasData()); // No sync tokens for software resources.
451 if (m_destructionInProgress || lostResource || m_isHidden || size != m_size) 434 if (m_destructionInProgress || lostResource || m_isHidden || size != m_size)
452 return; // Just delete the bitmap. 435 return; // Just delete the bitmap.
(...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after
575 } else { 558 } else {
576 GLenum format = 559 GLenum format =
577 defaultBufferRequiresAlphaChannelToBePreserved() ? GL_RGBA : GL_RGB; 560 defaultBufferRequiresAlphaChannelToBePreserved() ? GL_RGBA : GL_RGB;
578 parameters.creationInternalColorFormat = format; 561 parameters.creationInternalColorFormat = format;
579 parameters.internalColorFormat = format; 562 parameters.internalColorFormat = format;
580 parameters.colorFormat = format; 563 parameters.colorFormat = format;
581 } 564 }
582 return parameters; 565 return parameters;
583 } 566 }
584 567
585 PassRefPtr<DrawingBuffer::MailboxInfo> DrawingBuffer::takeRecycledMailbox() { 568 PassRefPtr<DrawingBuffer::ColorBuffer> DrawingBuffer::takeRecycledMailbox() {
586 if (m_recycledMailboxQueue.isEmpty()) 569 if (m_recycledMailboxQueue.isEmpty())
587 return nullptr; 570 return nullptr;
588 571
589 RefPtr<RecycledMailbox> recycled = m_recycledMailboxQueue.takeLast(); 572 RefPtr<ColorBuffer> recycled = m_recycledMailboxQueue.takeLast();
590 if (recycled->syncToken.HasData()) 573 DCHECK(recycled->size == m_size);
591 m_gl->WaitSyncTokenCHROMIUM(recycled->syncToken.GetData()); 574 if (recycled->receiveSyncToken.HasData())
592 575 m_gl->WaitSyncTokenCHROMIUM(recycled->receiveSyncToken.GetData());
593 RefPtr<MailboxInfo> mailboxInfo; 576 return recycled;
594 for (size_t i = 0; i < m_textureMailboxes.size(); i++) {
595 if (m_textureMailboxes[i]->mailbox == recycled->mailbox) {
596 mailboxInfo = m_textureMailboxes[i];
597 break;
598 }
599 }
600 DCHECK(mailboxInfo);
601 DCHECK(mailboxInfo->size == m_size);
602 return mailboxInfo.release();
603 } 577 }
604 578
605 PassRefPtr<DrawingBuffer::MailboxInfo> DrawingBuffer::createNewMailbox( 579 DrawingBuffer::ColorBuffer::ColorBuffer(DrawingBuffer* drawingBuffer,
606 const TextureInfo& info) { 580 const TextureParameters& parameters,
607 RefPtr<MailboxInfo> returnMailbox = adoptRef(new MailboxInfo); 581 const IntSize& size)
608 m_gl->GenMailboxCHROMIUM(returnMailbox->mailbox.name); 582 : drawingBuffer(drawingBuffer), parameters(parameters), size(size) {
609 returnMailbox->textureInfo = info; 583 drawingBuffer->contextGL()->GenMailboxCHROMIUM(mailbox.name);
610 returnMailbox->size = m_size;
611 m_textureMailboxes.append(returnMailbox);
612 return returnMailbox.release();
613 } 584 }
614 585
615 void DrawingBuffer::deleteMailbox(const gpu::Mailbox& mailbox, 586 DrawingBuffer::ColorBuffer::~ColorBuffer() {
616 const gpu::SyncToken& syncToken) { 587 gpu::gles2::GLES2Interface* gl = drawingBuffer->contextGL();
617 if (syncToken.HasData()) 588 if (receiveSyncToken.HasData())
618 m_gl->WaitSyncTokenCHROMIUM(syncToken.GetConstData()); 589 gl->WaitSyncTokenCHROMIUM(receiveSyncToken.GetConstData());
619 for (size_t i = 0; i < m_textureMailboxes.size(); i++) { 590 if (imageId) {
620 if (m_textureMailboxes[i]->mailbox == mailbox) { 591 gl->BindTexture(parameters.target, textureId);
621 deleteChromiumImageForTexture(&m_textureMailboxes[i]->textureInfo); 592 gl->ReleaseTexImage2DCHROMIUM(parameters.target, imageId);
622 m_gl->DeleteTextures(1, &m_textureMailboxes[i]->textureInfo.textureId); 593 gl->DestroyImageCHROMIUM(imageId);
623 m_textureMailboxes.remove(i);
624 return;
625 }
626 } 594 }
627 ASSERT_NOT_REACHED(); 595 gl->DeleteTextures(1, &textureId);
628 } 596 }
629 597
630 bool DrawingBuffer::initialize(const IntSize& size, bool useMultisampling) { 598 bool DrawingBuffer::initialize(const IntSize& size, bool useMultisampling) {
631 if (m_gl->GetGraphicsResetStatusKHR() != GL_NO_ERROR) { 599 if (m_gl->GetGraphicsResetStatusKHR() != GL_NO_ERROR) {
632 // Need to try to restore the context again later. 600 // Need to try to restore the context again later.
633 return false; 601 return false;
634 } 602 }
635 603
636 m_gl->GetIntegerv(GL_MAX_TEXTURE_SIZE, &m_maxTextureSize); 604 m_gl->GetIntegerv(GL_MAX_TEXTURE_SIZE, &m_maxTextureSize);
637 605
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after
699 m_gl->Flush(); 667 m_gl->Flush();
700 } 668 }
701 669
702 // Assume that the destination target is GL_TEXTURE_2D. 670 // Assume that the destination target is GL_TEXTURE_2D.
703 if (!Extensions3DUtil::canUseCopyTextureCHROMIUM( 671 if (!Extensions3DUtil::canUseCopyTextureCHROMIUM(
704 GL_TEXTURE_2D, internalFormat, destType, level)) 672 GL_TEXTURE_2D, internalFormat, destType, level))
705 return false; 673 return false;
706 674
707 // Contexts may be in a different share group. We must transfer the texture 675 // Contexts may be in a different share group. We must transfer the texture
708 // through a mailbox first. 676 // through a mailbox first.
709 GLint textureId = 0;
710 GLenum target = 0; 677 GLenum target = 0;
711 gpu::Mailbox mailbox; 678 gpu::Mailbox mailbox;
712 gpu::SyncToken produceSyncToken; 679 gpu::SyncToken produceSyncToken;
713 if (sourceBuffer == FrontBuffer && m_frontColorBuffer.texInfo.textureId) { 680 if (sourceBuffer == FrontBuffer && m_frontColorBuffer) {
714 textureId = m_frontColorBuffer.texInfo.textureId; 681 target = m_frontColorBuffer->parameters.target;
715 target = m_frontColorBuffer.texInfo.parameters.target; 682 mailbox = m_frontColorBuffer->mailbox;
716 mailbox = m_frontColorBuffer.mailbox; 683 produceSyncToken = m_frontColorBuffer->produceSyncToken;
717 produceSyncToken = m_frontColorBuffer.produceSyncToken;
718 } else { 684 } else {
719 textureId = m_colorBuffer.textureId; 685 target = m_backColorBuffer->parameters.target;
720 target = m_colorBuffer.parameters.target;
721 m_gl->GenMailboxCHROMIUM(mailbox.name); 686 m_gl->GenMailboxCHROMIUM(mailbox.name);
722 m_gl->ProduceTextureDirectCHROMIUM(textureId, target, mailbox.name); 687 m_gl->ProduceTextureDirectCHROMIUM(m_backColorBuffer->textureId, target,
688 mailbox.name);
723 const GLuint64 fenceSync = m_gl->InsertFenceSyncCHROMIUM(); 689 const GLuint64 fenceSync = m_gl->InsertFenceSyncCHROMIUM();
724 m_gl->Flush(); 690 m_gl->Flush();
725 m_gl->GenSyncTokenCHROMIUM(fenceSync, produceSyncToken.GetData()); 691 m_gl->GenSyncTokenCHROMIUM(fenceSync, produceSyncToken.GetData());
726 } 692 }
727 693
728 DCHECK(produceSyncToken.HasData()); 694 DCHECK(produceSyncToken.HasData());
729 gl->WaitSyncTokenCHROMIUM(produceSyncToken.GetConstData()); 695 gl->WaitSyncTokenCHROMIUM(produceSyncToken.GetConstData());
730 GLuint sourceTexture = 696 GLuint sourceTexture =
731 gl->CreateAndConsumeTextureCHROMIUM(target, mailbox.name); 697 gl->CreateAndConsumeTextureCHROMIUM(target, mailbox.name);
732 698
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
778 m_layer->clearTexture(); 744 m_layer->clearTexture();
779 745
780 m_gl->Flush(); 746 m_gl->Flush();
781 } 747 }
782 748
783 void DrawingBuffer::beginDestruction() { 749 void DrawingBuffer::beginDestruction() {
784 ASSERT(!m_destructionInProgress); 750 ASSERT(!m_destructionInProgress);
785 m_destructionInProgress = true; 751 m_destructionInProgress = true;
786 752
787 clearPlatformLayer(); 753 clearPlatformLayer();
788 freeRecycledMailboxes(); 754 m_recycledMailboxQueue.clear();
789 755
790 if (m_multisampleFBO) 756 if (m_multisampleFBO)
791 m_gl->DeleteFramebuffers(1, &m_multisampleFBO); 757 m_gl->DeleteFramebuffers(1, &m_multisampleFBO);
792 758
793 if (m_fbo) 759 if (m_fbo)
794 m_gl->DeleteFramebuffers(1, &m_fbo); 760 m_gl->DeleteFramebuffers(1, &m_fbo);
795 761
796 if (m_multisampleRenderbuffer) 762 if (m_multisampleRenderbuffer)
797 m_gl->DeleteRenderbuffers(1, &m_multisampleRenderbuffer); 763 m_gl->DeleteRenderbuffers(1, &m_multisampleRenderbuffer);
798 764
799 if (m_depthStencilBuffer) 765 if (m_depthStencilBuffer)
800 m_gl->DeleteRenderbuffers(1, &m_depthStencilBuffer); 766 m_gl->DeleteRenderbuffers(1, &m_depthStencilBuffer);
801 767
802 if (m_colorBuffer.textureId) {
803 deleteChromiumImageForTexture(&m_colorBuffer);
804 m_gl->DeleteTextures(1, &m_colorBuffer.textureId);
805 }
806
807 m_size = IntSize(); 768 m_size = IntSize();
808 769
809 m_colorBuffer = TextureInfo(); 770 m_backColorBuffer = nullptr;
810 m_frontColorBuffer = FrontBufferInfo(); 771 m_frontColorBuffer = nullptr;
811 m_multisampleRenderbuffer = 0; 772 m_multisampleRenderbuffer = 0;
812 m_depthStencilBuffer = 0; 773 m_depthStencilBuffer = 0;
813 m_multisampleFBO = 0; 774 m_multisampleFBO = 0;
814 m_fbo = 0; 775 m_fbo = 0;
815 776
816 if (m_layer) 777 if (m_layer)
817 GraphicsLayer::unregisterContentsLayer(m_layer->layer()); 778 GraphicsLayer::unregisterContentsLayer(m_layer->layer());
818 } 779 }
819 780
820 GLuint DrawingBuffer::createColorTexture(const TextureParameters& parameters) { 781 GLuint DrawingBuffer::createColorTexture(const TextureParameters& parameters) {
821 GLuint offscreenColorTexture; 782 GLuint offscreenColorTexture;
822 m_gl->GenTextures(1, &offscreenColorTexture); 783 m_gl->GenTextures(1, &offscreenColorTexture);
823 m_gl->BindTexture(parameters.target, offscreenColorTexture); 784 m_gl->BindTexture(parameters.target, offscreenColorTexture);
824 m_gl->TexParameteri(parameters.target, GL_TEXTURE_MAG_FILTER, GL_LINEAR); 785 m_gl->TexParameteri(parameters.target, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
825 m_gl->TexParameteri(parameters.target, GL_TEXTURE_MIN_FILTER, GL_LINEAR); 786 m_gl->TexParameteri(parameters.target, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
826 m_gl->TexParameteri(parameters.target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); 787 m_gl->TexParameteri(parameters.target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
827 m_gl->TexParameteri(parameters.target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); 788 m_gl->TexParameteri(parameters.target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
828 return offscreenColorTexture; 789 return offscreenColorTexture;
829 } 790 }
830 791
831 bool DrawingBuffer::resizeDefaultFramebuffer(const IntSize& size) { 792 bool DrawingBuffer::resizeDefaultFramebuffer(const IntSize& size) {
832 // Resize or create m_colorBuffer. 793 // Recreate m_backColorBuffer.
833 if (m_colorBuffer.textureId) { 794 m_backColorBuffer = createTextureAndAllocateMemory(size);
834 deleteChromiumImageForTexture(&m_colorBuffer);
835 m_gl->DeleteTextures(1, &m_colorBuffer.textureId);
836 }
837 m_colorBuffer = createTextureAndAllocateMemory(size);
838 795
839 attachColorBufferToReadFramebuffer(); 796 attachColorBufferToReadFramebuffer();
840 797
841 if (wantExplicitResolve()) { 798 if (wantExplicitResolve()) {
842 m_gl->BindFramebuffer(GL_FRAMEBUFFER, m_multisampleFBO); 799 m_gl->BindFramebuffer(GL_FRAMEBUFFER, m_multisampleFBO);
843 m_gl->BindRenderbuffer(GL_RENDERBUFFER, m_multisampleRenderbuffer); 800 m_gl->BindRenderbuffer(GL_RENDERBUFFER, m_multisampleRenderbuffer);
844 m_gl->RenderbufferStorageMultisampleCHROMIUM( 801 m_gl->RenderbufferStorageMultisampleCHROMIUM(
845 GL_RENDERBUFFER, m_sampleCount, getMultisampledRenderbufferFormat(), 802 GL_RENDERBUFFER, m_sampleCount, getMultisampledRenderbufferFormat(),
846 size.width(), size.height()); 803 size.width(), size.height());
847 804
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after
929 if (!resizeDefaultFramebuffer(adjustedSize)) { 886 if (!resizeDefaultFramebuffer(adjustedSize)) {
930 adjustedSize.scale(s_resourceAdjustedRatio); 887 adjustedSize.scale(s_resourceAdjustedRatio);
931 continue; 888 continue;
932 } 889 }
933 break; 890 break;
934 } while (!adjustedSize.isEmpty()); 891 } while (!adjustedSize.isEmpty());
935 892
936 m_size = adjustedSize; 893 m_size = adjustedSize;
937 // Free all mailboxes, because they are now of the wrong size. Only the 894 // Free all mailboxes, because they are now of the wrong size. Only the
938 // first call in this loop has any effect. 895 // first call in this loop has any effect.
939 freeRecycledMailboxes(); 896 m_recycledMailboxQueue.clear();
897 m_recycledBitmaps.clear();
940 898
941 if (adjustedSize.isEmpty()) 899 if (adjustedSize.isEmpty())
942 return false; 900 return false;
943 } 901 }
944 902
945 m_gl->Disable(GL_SCISSOR_TEST); 903 m_gl->Disable(GL_SCISSOR_TEST);
946 m_gl->ClearColor(0, 0, 0, 904 m_gl->ClearColor(0, 0, 0,
947 defaultBufferRequiresAlphaChannelToBePreserved() ? 1 : 0); 905 defaultBufferRequiresAlphaChannelToBePreserved() ? 1 : 0);
948 m_gl->ColorMask(true, true, true, true); 906 m_gl->ColorMask(true, true, true, true);
949 907
(...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after
1062 dataSize *= width; 1020 dataSize *= width;
1063 dataSize *= height; 1021 dataSize *= height;
1064 if (!dataSize.IsValid()) 1022 if (!dataSize.IsValid())
1065 return false; 1023 return false;
1066 1024
1067 WTF::ArrayBufferContents pixels(width * height, 4, 1025 WTF::ArrayBufferContents pixels(width * height, 4,
1068 WTF::ArrayBufferContents::NotShared, 1026 WTF::ArrayBufferContents::NotShared,
1069 WTF::ArrayBufferContents::DontInitialize); 1027 WTF::ArrayBufferContents::DontInitialize);
1070 1028
1071 GLuint fbo = 0; 1029 GLuint fbo = 0;
1072 if (sourceBuffer == FrontBuffer && m_frontColorBuffer.texInfo.textureId) { 1030 if (sourceBuffer == FrontBuffer && m_frontColorBuffer) {
1073 m_gl->GenFramebuffers(1, &fbo); 1031 m_gl->GenFramebuffers(1, &fbo);
1074 m_gl->BindFramebuffer(GL_FRAMEBUFFER, fbo); 1032 m_gl->BindFramebuffer(GL_FRAMEBUFFER, fbo);
1075 m_gl->FramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, 1033 m_gl->FramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
1076 m_frontColorBuffer.texInfo.parameters.target, 1034 m_frontColorBuffer->parameters.target,
1077 m_frontColorBuffer.texInfo.textureId, 0); 1035 m_frontColorBuffer->textureId, 0);
1078 } else { 1036 } else {
1079 m_gl->BindFramebuffer(GL_FRAMEBUFFER, framebuffer()); 1037 m_gl->BindFramebuffer(GL_FRAMEBUFFER, framebuffer());
1080 } 1038 }
1081 1039
1082 readBackFramebuffer(static_cast<unsigned char*>(pixels.data()), width, height, 1040 readBackFramebuffer(static_cast<unsigned char*>(pixels.data()), width, height,
1083 ReadbackRGBA, WebGLImageConversion::AlphaDoNothing); 1041 ReadbackRGBA, WebGLImageConversion::AlphaDoNothing);
1084 flipVertically(static_cast<uint8_t*>(pixels.data()), width, height); 1042 flipVertically(static_cast<uint8_t*>(pixels.data()), width, height);
1085 1043
1086 if (fbo) { 1044 if (fbo) {
1087 m_gl->FramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, 1045 m_gl->FramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
1088 m_frontColorBuffer.texInfo.parameters.target, 0, 1046 m_frontColorBuffer->parameters.target, 0, 0);
1089 0);
1090 m_gl->DeleteFramebuffers(1, &fbo); 1047 m_gl->DeleteFramebuffers(1, &fbo);
1091 } 1048 }
1092 1049
1093 restoreFramebufferBindings(); 1050 restoreFramebufferBindings();
1094 1051
1095 pixels.transfer(contents); 1052 pixels.transfer(contents);
1096 return true; 1053 return true;
1097 } 1054 }
1098 1055
1099 void DrawingBuffer::readBackFramebuffer(unsigned char* pixels, 1056 void DrawingBuffer::readBackFramebuffer(unsigned char* pixels,
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after
1163 NOTREACHED(); 1120 NOTREACHED();
1164 } 1121 }
1165 m_gl->TexStorage2DEXT(GL_TEXTURE_2D, 1, internalStorageFormat, width, 1122 m_gl->TexStorage2DEXT(GL_TEXTURE_2D, 1, internalStorageFormat, width,
1166 height); 1123 height);
1167 return; 1124 return;
1168 } 1125 }
1169 m_gl->TexImage2D(target, 0, internalformat, width, height, border, format, 1126 m_gl->TexImage2D(target, 0, internalformat, width, height, border, format,
1170 type, 0); 1127 type, 0);
1171 } 1128 }
1172 1129
1173 void DrawingBuffer::deleteChromiumImageForTexture(TextureInfo* info) { 1130 void DrawingBuffer::clearChromiumImageAlpha(const ColorBuffer& info) {
1174 if (info->imageId) {
1175 m_gl->BindTexture(info->parameters.target, info->textureId);
1176 m_gl->ReleaseTexImage2DCHROMIUM(info->parameters.target, info->imageId);
1177 m_gl->DestroyImageCHROMIUM(info->imageId);
1178 info->imageId = 0;
1179 }
1180 }
1181
1182 void DrawingBuffer::clearChromiumImageAlpha(const TextureInfo& info) {
1183 if (m_wantAlphaChannel) 1131 if (m_wantAlphaChannel)
1184 return; 1132 return;
1185 if (!contextProvider()->getCapabilities().chromium_image_rgb_emulation) 1133 if (!contextProvider()->getCapabilities().chromium_image_rgb_emulation)
1186 return; 1134 return;
1187 1135
1188 GLuint fbo = 0; 1136 GLuint fbo = 0;
1189 m_gl->GenFramebuffers(1, &fbo); 1137 m_gl->GenFramebuffers(1, &fbo);
1190 m_gl->BindFramebuffer(GL_FRAMEBUFFER, fbo); 1138 m_gl->BindFramebuffer(GL_FRAMEBUFFER, fbo);
1191 m_gl->FramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, 1139 m_gl->FramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
1192 info.parameters.target, info.textureId, 0); 1140 info.parameters.target, info.textureId, 0);
1193 m_gl->ClearColor(0, 0, 0, 1); 1141 m_gl->ClearColor(0, 0, 0, 1);
1194 m_gl->ColorMask(false, false, false, true); 1142 m_gl->ColorMask(false, false, false, true);
1195 m_gl->Clear(GL_COLOR_BUFFER_BIT); 1143 m_gl->Clear(GL_COLOR_BUFFER_BIT);
1196 m_gl->FramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, 1144 m_gl->FramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
1197 info.parameters.target, 0, 0); 1145 info.parameters.target, 0, 0);
1198 m_gl->DeleteFramebuffers(1, &fbo); 1146 m_gl->DeleteFramebuffers(1, &fbo);
1199 restoreFramebufferBindings(); 1147 restoreFramebufferBindings();
1200 m_gl->ClearColor(m_clearColor[0], m_clearColor[1], m_clearColor[2], 1148 m_gl->ClearColor(m_clearColor[0], m_clearColor[1], m_clearColor[2],
1201 m_clearColor[3]); 1149 m_clearColor[3]);
1202 m_gl->ColorMask(m_colorMask[0], m_colorMask[1], m_colorMask[2], 1150 m_gl->ColorMask(m_colorMask[0], m_colorMask[1], m_colorMask[2],
1203 m_colorMask[3]); 1151 m_colorMask[3]);
1204 } 1152 }
1205 1153
1206 DrawingBuffer::TextureInfo DrawingBuffer::createTextureAndAllocateMemory( 1154 RefPtr<DrawingBuffer::ColorBuffer>
1207 const IntSize& size) { 1155 DrawingBuffer::createTextureAndAllocateMemory(const IntSize& size) {
1208 if (!shouldUseChromiumImage()) 1156 if (!shouldUseChromiumImage())
1209 return createDefaultTextureAndAllocateMemory(size); 1157 return createDefaultTextureAndAllocateMemory(size);
1210 1158
1211 TextureParameters parameters = chromiumImageTextureParameters(); 1159 TextureParameters parameters = chromiumImageTextureParameters();
1212 GLuint imageId = m_gl->CreateGpuMemoryBufferImageCHROMIUM( 1160 GLuint imageId = m_gl->CreateGpuMemoryBufferImageCHROMIUM(
1213 size.width(), size.height(), parameters.creationInternalColorFormat, 1161 size.width(), size.height(), parameters.creationInternalColorFormat,
1214 GC3D_SCANOUT_CHROMIUM); 1162 GC3D_SCANOUT_CHROMIUM);
1215 GLuint textureId = createColorTexture(parameters); 1163 GLuint textureId = createColorTexture(parameters);
1216 if (imageId) { 1164 if (imageId) {
1217 m_gl->BindTexImage2DCHROMIUM(parameters.target, imageId); 1165 m_gl->BindTexImage2DCHROMIUM(parameters.target, imageId);
1218 } 1166 }
1219 1167
1220 TextureInfo info; 1168 RefPtr<ColorBuffer> info(adoptRef(new ColorBuffer(this, parameters, size)));
1221 info.textureId = textureId; 1169 info->textureId = textureId;
1222 info.imageId = imageId; 1170 info->imageId = imageId;
1223 info.parameters = parameters; 1171 clearChromiumImageAlpha(*info);
1224 clearChromiumImageAlpha(info);
1225 return info; 1172 return info;
1226 } 1173 }
1227 1174
1228 DrawingBuffer::TextureInfo DrawingBuffer::createDefaultTextureAndAllocateMemory( 1175 RefPtr<DrawingBuffer::ColorBuffer>
1229 const IntSize& size) { 1176 DrawingBuffer::createDefaultTextureAndAllocateMemory(const IntSize& size) {
1230 DrawingBuffer::TextureInfo info;
1231 TextureParameters parameters = defaultTextureParameters(); 1177 TextureParameters parameters = defaultTextureParameters();
1232 info.parameters = parameters; 1178 RefPtr<ColorBuffer> info(adoptRef(new ColorBuffer(this, parameters, size)));
1233 info.textureId = createColorTexture(parameters); 1179 info->textureId = createColorTexture(parameters);
1234 allocateConditionallyImmutableTexture( 1180 allocateConditionallyImmutableTexture(
1235 parameters.target, parameters.creationInternalColorFormat, size.width(), 1181 parameters.target, parameters.creationInternalColorFormat, size.width(),
1236 size.height(), 0, parameters.colorFormat, GL_UNSIGNED_BYTE); 1182 size.height(), 0, parameters.colorFormat, GL_UNSIGNED_BYTE);
1237 return info; 1183 return info;
1238 } 1184 }
1239 1185
1240 void DrawingBuffer::attachColorBufferToReadFramebuffer() { 1186 void DrawingBuffer::attachColorBufferToReadFramebuffer() {
1241 m_gl->BindFramebuffer(GL_FRAMEBUFFER, m_fbo); 1187 m_gl->BindFramebuffer(GL_FRAMEBUFFER, m_fbo);
1242 1188
1243 GLenum target = m_colorBuffer.parameters.target; 1189 GLenum target = m_backColorBuffer->parameters.target;
1244 GLenum id = m_colorBuffer.textureId; 1190 GLenum id = m_backColorBuffer->textureId;
1245 1191
1246 m_gl->BindTexture(target, id); 1192 m_gl->BindTexture(target, id);
1247 1193
1248 if (m_antiAliasingMode == MSAAImplicitResolve) 1194 if (m_antiAliasingMode == MSAAImplicitResolve)
1249 m_gl->FramebufferTexture2DMultisampleEXT( 1195 m_gl->FramebufferTexture2DMultisampleEXT(
1250 GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, target, id, 0, m_sampleCount); 1196 GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, target, id, 0, m_sampleCount);
1251 else 1197 else
1252 m_gl->FramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, target, id, 1198 m_gl->FramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, target, id,
1253 0); 1199 0);
1254 1200
(...skipping 29 matching lines...) Expand all
1284 // the public interface for WebGL does not support GL_TEXTURE_RECTANGLE. 1230 // the public interface for WebGL does not support GL_TEXTURE_RECTANGLE.
1285 m_gl->BindTexture(GL_TEXTURE_2D, m_texture2DBinding); 1231 m_gl->BindTexture(GL_TEXTURE_2D, m_texture2DBinding);
1286 } 1232 }
1287 1233
1288 bool DrawingBuffer::shouldUseChromiumImage() { 1234 bool DrawingBuffer::shouldUseChromiumImage() {
1289 return RuntimeEnabledFeatures::webGLImageChromiumEnabled() && 1235 return RuntimeEnabledFeatures::webGLImageChromiumEnabled() &&
1290 m_chromiumImageUsage == AllowChromiumImage; 1236 m_chromiumImageUsage == AllowChromiumImage;
1291 } 1237 }
1292 1238
1293 } // namespace blink 1239 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698