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

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

Issue 2397713005: DrawingBuffer clean-up: Aesthetic changes (Closed)
Patch Set: Fix alpha clearing behavior 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
« no previous file with comments | « third_party/WebKit/Source/platform/graphics/gpu/DrawingBuffer.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 199 matching lines...) Expand 10 before | Expand all | Expand 10 after
210 210
211 WebGraphicsContext3DProvider* DrawingBuffer::contextProvider() { 211 WebGraphicsContext3DProvider* DrawingBuffer::contextProvider() {
212 return m_contextProvider.get(); 212 return m_contextProvider.get();
213 } 213 }
214 214
215 void DrawingBuffer::setIsHidden(bool hidden) { 215 void DrawingBuffer::setIsHidden(bool hidden) {
216 if (m_isHidden == hidden) 216 if (m_isHidden == hidden)
217 return; 217 return;
218 m_isHidden = hidden; 218 m_isHidden = hidden;
219 if (m_isHidden) 219 if (m_isHidden)
220 m_recycledMailboxQueue.clear(); 220 m_recycledColorBufferQueue.clear();
221 } 221 }
222 222
223 void DrawingBuffer::setFilterQuality(SkFilterQuality filterQuality) { 223 void DrawingBuffer::setFilterQuality(SkFilterQuality filterQuality) {
224 if (m_filterQuality != filterQuality) { 224 if (m_filterQuality != filterQuality) {
225 m_filterQuality = filterQuality; 225 m_filterQuality = filterQuality;
226 if (m_layer) 226 if (m_layer)
227 m_layer->setNearestNeighbor(filterQuality == kNone_SkFilterQuality); 227 m_layer->setNearestNeighbor(filterQuality == kNone_SkFilterQuality);
228 } 228 }
229 } 229 }
230 230
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after
295 TRACE_EVENT0("blink,rail", "DrawingBuffer::prepareMailbox"); 295 TRACE_EVENT0("blink,rail", "DrawingBuffer::prepareMailbox");
296 296
297 if (m_newMailboxCallback) 297 if (m_newMailboxCallback)
298 (*m_newMailboxCallback)(); 298 (*m_newMailboxCallback)();
299 299
300 // Resolve the multisampled buffer into m_backColorBuffer texture. 300 // Resolve the multisampled buffer into m_backColorBuffer texture.
301 if (m_antiAliasingMode != None) 301 if (m_antiAliasingMode != None)
302 commit(); 302 commit();
303 303
304 if (m_softwareRendering && !forceGpuResult) { 304 if (m_softwareRendering && !forceGpuResult) {
305 std::unique_ptr<cc::SharedBitmap> bitmap = createOrRecycleBitmap(); 305 return finishPrepareTextureMailboxSoftware(outMailbox, outReleaseCallback);
306 if (!bitmap) 306 } else {
307 return false; 307 return finishPrepareTextureMailboxGpu(outMailbox, outReleaseCallback);
308 }
309 }
310
311 bool DrawingBuffer::finishPrepareTextureMailboxSoftware(
312 cc::TextureMailbox* outMailbox,
313 std::unique_ptr<cc::SingleReleaseCallback>* outReleaseCallback) {
314 std::unique_ptr<cc::SharedBitmap> bitmap = createOrRecycleBitmap();
315 if (!bitmap)
316 return false;
317
318 // Read the framebuffer into |bitmap|.
319 {
erikchen 2016/10/07 16:25:09 why the new scope?
ccameron 2016/10/07 20:36:30 Two reasons: - it makes it clear what the steps in
308 unsigned char* pixels = bitmap->pixels(); 320 unsigned char* pixels = bitmap->pixels();
309 DCHECK(pixels); 321 DCHECK(pixels);
310
311 bool needPremultiply = m_wantAlphaChannel && !m_premultipliedAlpha; 322 bool needPremultiply = m_wantAlphaChannel && !m_premultipliedAlpha;
312 WebGLImageConversion::AlphaOp op = 323 WebGLImageConversion::AlphaOp op =
313 needPremultiply ? WebGLImageConversion::AlphaDoPremultiply 324 needPremultiply ? WebGLImageConversion::AlphaDoPremultiply
314 : WebGLImageConversion::AlphaDoNothing; 325 : WebGLImageConversion::AlphaDoNothing;
315 readBackFramebuffer(pixels, size().width(), size().height(), ReadbackSkia, 326 readBackFramebuffer(pixels, size().width(), size().height(), ReadbackSkia,
316 op); 327 op);
317
318 *outMailbox = cc::TextureMailbox(bitmap.get(), m_size);
319
320 // This holds a ref on the DrawingBuffer that will keep it alive until the
321 // mailbox is released (and while the release callback is running). It also
322 // owns the SharedBitmap.
323 auto func = WTF::bind(&DrawingBuffer::softwareMailboxReleased,
324 RefPtr<DrawingBuffer>(this),
325 WTF::passed(std::move(bitmap)), m_size);
326 *outReleaseCallback = cc::SingleReleaseCallback::Create(
327 convertToBaseCallback(std::move(func)));
328 return true;
329 } 328 }
330 329
330 *outMailbox = cc::TextureMailbox(bitmap.get(), m_size);
331
332 // This holds a ref on the DrawingBuffer that will keep it alive until the
333 // mailbox is released (and while the release callback is running). It also
334 // owns the SharedBitmap.
335 auto func = WTF::bind(&DrawingBuffer::mailboxReleasedSoftware,
336 RefPtr<DrawingBuffer>(this),
337 WTF::passed(std::move(bitmap)), m_size);
338 *outReleaseCallback =
339 cc::SingleReleaseCallback::Create(convertToBaseCallback(std::move(func)));
340 return true;
341 }
342
343 bool DrawingBuffer::finishPrepareTextureMailboxGpu(
344 cc::TextureMailbox* outMailbox,
345 std::unique_ptr<cc::SingleReleaseCallback>* outReleaseCallback) {
331 if (m_webGLVersion > WebGL1) { 346 if (m_webGLVersion > WebGL1) {
332 m_gl->BindBuffer(GL_PIXEL_UNPACK_BUFFER, 0); 347 m_gl->BindBuffer(GL_PIXEL_UNPACK_BUFFER, 0);
333 } 348 }
334 349
335 // We must restore the texture binding since creating new textures, 350 // We must restore the texture binding since creating new textures,
336 // consuming and producing mailboxes changes it. 351 // consuming and producing mailboxes changes it.
337 ScopedTextureUnit0BindingRestorer restorer(m_gl, m_activeTextureUnit, 352 ScopedTextureUnit0BindingRestorer restorer(m_gl, m_activeTextureUnit,
338 m_texture2DBinding); 353 m_texture2DBinding);
339 354
340 // First try to recycle an old buffer. 355 // Specify the buffer that we will put in the mailbox.
341 RefPtr<ColorBuffer> colorBufferForMailbox = takeRecycledMailbox(); 356 RefPtr<ColorBuffer> colorBufferForMailbox;
342
343 // No buffer available to recycle, create a new one.
344 if (!colorBufferForMailbox)
345 colorBufferForMailbox = createTextureAndAllocateMemory(m_size);
346
347 if (m_preserveDrawingBuffer == Discard) { 357 if (m_preserveDrawingBuffer == Discard) {
348 std::swap(colorBufferForMailbox, m_backColorBuffer); 358 // If we can discard the backbuffer, send the old backbuffer directly
359 // into the mailbox, and allocate (or recycle) a new backbuffer.
360 colorBufferForMailbox = m_backColorBuffer;
361 m_backColorBuffer = createOrRecycleColorBuffer();
349 attachColorBufferToReadFramebuffer(); 362 attachColorBufferToReadFramebuffer();
350 363
364 // 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
366 // tile-based GPU architectures.
351 if (m_discardFramebufferSupported) { 367 if (m_discardFramebufferSupported) {
352 // Explicitly discard the framebuffer to save GPU memory bandwidth for
353 // tile-based GPU arch.
354 const GLenum attachments[3] = {GL_COLOR_ATTACHMENT0, GL_DEPTH_ATTACHMENT, 368 const GLenum attachments[3] = {GL_COLOR_ATTACHMENT0, GL_DEPTH_ATTACHMENT,
355 GL_STENCIL_ATTACHMENT}; 369 GL_STENCIL_ATTACHMENT};
356 m_gl->BindFramebuffer(GL_FRAMEBUFFER, m_fbo); 370 m_gl->BindFramebuffer(GL_FRAMEBUFFER, m_fbo);
357 m_gl->DiscardFramebufferEXT(GL_FRAMEBUFFER, 3, attachments); 371 m_gl->DiscardFramebufferEXT(GL_FRAMEBUFFER, 3, attachments);
358 } 372 }
359 } else { 373 } else {
374 // If we can't discard the backbuffer, create (or recycle) a buffer to put
375 // in the mailbox, and copy backbuffer's contents there.
376 colorBufferForMailbox = createOrRecycleColorBuffer();
360 m_gl->CopySubTextureCHROMIUM( 377 m_gl->CopySubTextureCHROMIUM(
361 m_backColorBuffer->textureId, colorBufferForMailbox->textureId, 0, 0, 0, 378 m_backColorBuffer->textureId, colorBufferForMailbox->textureId, 0, 0, 0,
362 0, m_size.width(), m_size.height(), GL_FALSE, GL_FALSE, GL_FALSE); 379 0, m_size.width(), m_size.height(), GL_FALSE, GL_FALSE, GL_FALSE);
363 } 380 }
364 381
382 // Put colorBufferForMailbox into its mailbox, and populate its
383 // produceSyncToken with that point.
384 {
385 m_gl->ProduceTextureDirectCHROMIUM(colorBufferForMailbox->textureId,
386 colorBufferForMailbox->parameters.target,
387 colorBufferForMailbox->mailbox.name);
388 const GLuint64 fenceSync = m_gl->InsertFenceSyncCHROMIUM();
389 #if OS(MACOSX)
390 m_gl->DescheduleUntilFinishedCHROMIUM();
391 #endif
392 m_gl->Flush();
393 m_gl->GenSyncTokenCHROMIUM(
394 fenceSync, colorBufferForMailbox->produceSyncToken.GetData());
395 }
396
397 // Populate the output mailbox and callback.
398 {
399 bool isOverlayCandidate = colorBufferForMailbox->imageId != 0;
400 bool secureOutputOnly = false;
401 *outMailbox = cc::TextureMailbox(
402 colorBufferForMailbox->mailbox, colorBufferForMailbox->produceSyncToken,
403 colorBufferForMailbox->parameters.target, gfx::Size(m_size),
404 isOverlayCandidate, secureOutputOnly);
405
406 // This holds a ref on the DrawingBuffer that will keep it alive until the
407 // mailbox is released (and while the release callback is running).
408 auto func = WTF::bind(&DrawingBuffer::mailboxReleasedGpu,
409 RefPtr<DrawingBuffer>(this), colorBufferForMailbox);
410 *outReleaseCallback = cc::SingleReleaseCallback::Create(
411 convertToBaseCallback(std::move(func)));
412 }
413
414 // Point |m_frontColorBuffer| to the buffer that we are now presenting.
415 m_frontColorBuffer = colorBufferForMailbox;
416
417 // Restore any state that we may have dirtied, and update dirty bits.
365 restoreFramebufferBindings(); 418 restoreFramebufferBindings();
366 restorePixelUnpackBufferBindings(); 419 restorePixelUnpackBufferBindings();
367 m_contentsChanged = false; 420 m_contentsChanged = false;
368
369 m_gl->ProduceTextureDirectCHROMIUM(colorBufferForMailbox->textureId,
370 colorBufferForMailbox->parameters.target,
371 colorBufferForMailbox->mailbox.name);
372 const GLuint64 fenceSync = m_gl->InsertFenceSyncCHROMIUM();
373 #if OS(MACOSX)
374 m_gl->DescheduleUntilFinishedCHROMIUM();
375 #endif
376 m_gl->Flush();
377 gpu::SyncToken syncToken;
378 m_gl->GenSyncTokenCHROMIUM(fenceSync, syncToken.GetData());
379
380 bool isOverlayCandidate = colorBufferForMailbox->imageId != 0;
381 bool secureOutputOnly = false;
382 *outMailbox = cc::TextureMailbox(colorBufferForMailbox->mailbox, syncToken,
383 colorBufferForMailbox->parameters.target,
384 gfx::Size(m_size.width(), m_size.height()),
385 isOverlayCandidate, secureOutputOnly);
386
387 // This holds a ref on the DrawingBuffer that will keep it alive until the
388 // mailbox is released (and while the release callback is running).
389 auto func = WTF::bind(&DrawingBuffer::gpuMailboxReleased,
390 RefPtr<DrawingBuffer>(this), colorBufferForMailbox);
391 *outReleaseCallback =
392 cc::SingleReleaseCallback::Create(convertToBaseCallback(std::move(func)));
393
394 // Point |m_frontColorBuffer| to the buffer that we are presenting, and
395 // update its sync token.
396 colorBufferForMailbox->produceSyncToken = syncToken;
397 m_frontColorBuffer = colorBufferForMailbox;
398 setBufferClearNeeded(true); 421 setBufferClearNeeded(true);
399 return true; 422 return true;
400 } 423 }
401 424
402 void DrawingBuffer::gpuMailboxReleased(RefPtr<ColorBuffer> colorBuffer, 425 void DrawingBuffer::mailboxReleasedGpu(RefPtr<ColorBuffer> colorBuffer,
403 const gpu::SyncToken& syncToken, 426 const gpu::SyncToken& syncToken,
404 bool lostResource) { 427 bool lostResource) {
405 // If the mailbox has been returned by the compositor then it is no 428 // If the mailbox has been returned by the compositor then it is no
406 // longer being presented, and so is no longer the front buffer. 429 // longer being presented, and so is no longer the front buffer.
407 if (colorBuffer == m_frontColorBuffer) 430 if (colorBuffer == m_frontColorBuffer)
408 m_frontColorBuffer = nullptr; 431 m_frontColorBuffer = nullptr;
409 432
410 // Update the SyncToken to ensure that we will wait for it even if we 433 // Update the SyncToken to ensure that we will wait for it even if we
411 // immediately destroy this buffer. 434 // immediately destroy this buffer.
412 colorBuffer->receiveSyncToken = syncToken; 435 colorBuffer->receiveSyncToken = syncToken;
413 436
414 if (m_destructionInProgress || colorBuffer->size != m_size || 437 if (m_destructionInProgress || colorBuffer->size != m_size ||
415 m_gl->GetGraphicsResetStatusKHR() != GL_NO_ERROR || lostResource || 438 m_gl->GetGraphicsResetStatusKHR() != GL_NO_ERROR || lostResource ||
416 m_isHidden) { 439 m_isHidden) {
417 return; 440 return;
418 } 441 }
419 442
420 // Creation of image backed mailboxes is very expensive, so be less 443 // Creation of image backed mailboxes is very expensive, so be less
421 // aggressive about pruning them. Pruning is done in FIFO order. 444 // aggressive about pruning them. Pruning is done in FIFO order.
422 size_t cacheLimit = 1; 445 size_t cacheLimit = 1;
423 if (shouldUseChromiumImage()) 446 if (shouldUseChromiumImage())
424 cacheLimit = 4; 447 cacheLimit = 4;
425 while (m_recycledMailboxQueue.size() >= cacheLimit) 448 while (m_recycledColorBufferQueue.size() >= cacheLimit)
426 m_recycledMailboxQueue.takeLast(); 449 m_recycledColorBufferQueue.takeLast();
427 450
428 m_recycledMailboxQueue.prepend(colorBuffer); 451 m_recycledColorBufferQueue.prepend(colorBuffer);
429 } 452 }
430 453
431 void DrawingBuffer::softwareMailboxReleased( 454 void DrawingBuffer::mailboxReleasedSoftware(
432 std::unique_ptr<cc::SharedBitmap> bitmap, 455 std::unique_ptr<cc::SharedBitmap> bitmap,
433 const IntSize& size, 456 const IntSize& size,
434 const gpu::SyncToken& syncToken, 457 const gpu::SyncToken& syncToken,
435 bool lostResource) { 458 bool lostResource) {
436 DCHECK(!syncToken.HasData()); // No sync tokens for software resources. 459 DCHECK(!syncToken.HasData()); // No sync tokens for software resources.
437 if (m_destructionInProgress || lostResource || m_isHidden || size != m_size) 460 if (m_destructionInProgress || lostResource || m_isHidden || size != m_size)
438 return; // Just delete the bitmap. 461 return; // Just delete the bitmap.
439 462
440 RecycledBitmap recycled = {std::move(bitmap), m_size}; 463 RecycledBitmap recycled = {std::move(bitmap), m_size};
441 m_recycledBitmaps.append(std::move(recycled)); 464 m_recycledBitmaps.append(std::move(recycled));
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
507 // DrawingBuffer's context anyways. 530 // DrawingBuffer's context anyways.
508 const auto& skImageSyncToken = textureMailbox.sync_token(); 531 const auto& skImageSyncToken = textureMailbox.sync_token();
509 532
510 // TODO(xidachen): Create a small pool of recycled textures from 533 // TODO(xidachen): Create a small pool of recycled textures from
511 // ImageBitmapRenderingContext's transferFromImageBitmap, and try to use them 534 // ImageBitmapRenderingContext's transferFromImageBitmap, and try to use them
512 // in DrawingBuffer. 535 // in DrawingBuffer.
513 return AcceleratedStaticBitmapImage::createFromWebGLContextImage( 536 return AcceleratedStaticBitmapImage::createFromWebGLContextImage(
514 std::move(skImage), skImageMailbox, skImageSyncToken); 537 std::move(skImage), skImageMailbox, skImageSyncToken);
515 } 538 }
516 539
517 DrawingBuffer::TextureParameters 540 DrawingBuffer::ColorBufferParameters
518 DrawingBuffer::chromiumImageTextureParameters() { 541 DrawingBuffer::gpuMemoryBufferColorBufferParameters() {
519 #if OS(MACOSX) 542 #if OS(MACOSX)
520 // A CHROMIUM_image backed texture requires a specialized set of parameters 543 // A CHROMIUM_image backed texture requires a specialized set of parameters
521 // on OSX. 544 // on OSX.
522 TextureParameters parameters; 545 ColorBufferParameters parameters;
523 parameters.target = GC3D_TEXTURE_RECTANGLE_ARB; 546 parameters.target = GC3D_TEXTURE_RECTANGLE_ARB;
524 547
525 if (m_wantAlphaChannel) { 548 if (m_wantAlphaChannel) {
526 parameters.creationInternalColorFormat = GL_RGBA; 549 parameters.creationInternalColorFormat = GL_RGBA;
527 parameters.internalColorFormat = GL_RGBA; 550 parameters.internalColorFormat = GL_RGBA;
528 } else if (contextProvider() 551 } else if (contextProvider()
529 ->getCapabilities() 552 ->getCapabilities()
530 .chromium_image_rgb_emulation) { 553 .chromium_image_rgb_emulation) {
531 parameters.creationInternalColorFormat = GL_RGB; 554 parameters.creationInternalColorFormat = GL_RGB;
532 parameters.internalColorFormat = GL_RGBA; 555 parameters.internalColorFormat = GL_RGBA;
533 } else { 556 } else {
534 GLenum format = 557 GLenum format =
535 defaultBufferRequiresAlphaChannelToBePreserved() ? GL_RGBA : GL_RGB; 558 defaultBufferRequiresAlphaChannelToBePreserved() ? GL_RGBA : GL_RGB;
536 parameters.creationInternalColorFormat = format; 559 parameters.creationInternalColorFormat = format;
537 parameters.internalColorFormat = format; 560 parameters.internalColorFormat = format;
538 } 561 }
539 562
540 // Unused when CHROMIUM_image is being used. 563 // Unused when CHROMIUM_image is being used.
541 parameters.colorFormat = 0; 564 parameters.colorFormat = 0;
542 return parameters; 565 return parameters;
543 #else 566 #else
544 return defaultTextureParameters(); 567 return textureColorBufferParameters();
545 #endif 568 #endif
546 } 569 }
547 570
548 DrawingBuffer::TextureParameters DrawingBuffer::defaultTextureParameters() { 571 DrawingBuffer::ColorBufferParameters
549 TextureParameters parameters; 572 DrawingBuffer::textureColorBufferParameters() {
573 ColorBufferParameters parameters;
550 parameters.target = GL_TEXTURE_2D; 574 parameters.target = GL_TEXTURE_2D;
551 if (m_wantAlphaChannel) { 575 if (m_wantAlphaChannel) {
552 parameters.internalColorFormat = GL_RGBA; 576 parameters.internalColorFormat = GL_RGBA;
553 parameters.creationInternalColorFormat = GL_RGBA; 577 parameters.creationInternalColorFormat = GL_RGBA;
554 parameters.colorFormat = GL_RGBA; 578 parameters.colorFormat = GL_RGBA;
555 } else if (contextProvider() 579 } else if (contextProvider()
556 ->getCapabilities() 580 ->getCapabilities()
557 .emulate_rgb_buffer_with_rgba) { 581 .emulate_rgb_buffer_with_rgba) {
558 parameters.internalColorFormat = GL_RGBA; 582 parameters.internalColorFormat = GL_RGBA;
559 parameters.creationInternalColorFormat = GL_RGBA; 583 parameters.creationInternalColorFormat = GL_RGBA;
560 parameters.colorFormat = GL_RGBA; 584 parameters.colorFormat = GL_RGBA;
561 } else { 585 } else {
562 GLenum format = 586 GLenum format =
563 defaultBufferRequiresAlphaChannelToBePreserved() ? GL_RGBA : GL_RGB; 587 defaultBufferRequiresAlphaChannelToBePreserved() ? GL_RGBA : GL_RGB;
564 parameters.creationInternalColorFormat = format; 588 parameters.creationInternalColorFormat = format;
565 parameters.internalColorFormat = format; 589 parameters.internalColorFormat = format;
566 parameters.colorFormat = format; 590 parameters.colorFormat = format;
567 } 591 }
568 return parameters; 592 return parameters;
569 } 593 }
570 594
571 PassRefPtr<DrawingBuffer::ColorBuffer> DrawingBuffer::takeRecycledMailbox() { 595 PassRefPtr<DrawingBuffer::ColorBuffer>
572 if (m_recycledMailboxQueue.isEmpty()) 596 DrawingBuffer::createOrRecycleColorBuffer() {
573 return nullptr; 597 if (!m_recycledColorBufferQueue.isEmpty()) {
574 598 RefPtr<ColorBuffer> recycled = m_recycledColorBufferQueue.takeLast();
575 RefPtr<ColorBuffer> recycled = m_recycledMailboxQueue.takeLast(); 599 if (recycled->receiveSyncToken.HasData())
576 DCHECK(recycled->size == m_size); 600 m_gl->WaitSyncTokenCHROMIUM(recycled->receiveSyncToken.GetData());
577 if (recycled->receiveSyncToken.HasData()) 601 DCHECK(recycled->size == m_size);
578 m_gl->WaitSyncTokenCHROMIUM(recycled->receiveSyncToken.GetData()); 602 return recycled;
579 return recycled; 603 }
604 return createColorBuffer(m_size);
580 } 605 }
581 606
582 DrawingBuffer::ColorBuffer::ColorBuffer(DrawingBuffer* drawingBuffer, 607 DrawingBuffer::ColorBuffer::ColorBuffer(DrawingBuffer* drawingBuffer,
583 const TextureParameters& parameters, 608 const ColorBufferParameters& parameters,
584 const IntSize& size) 609 const IntSize& size,
585 : drawingBuffer(drawingBuffer), parameters(parameters), size(size) { 610 GLuint textureId,
611 GLuint imageId)
612 : drawingBuffer(drawingBuffer),
613 parameters(parameters),
614 size(size),
615 textureId(textureId),
616 imageId(imageId) {
586 drawingBuffer->contextGL()->GenMailboxCHROMIUM(mailbox.name); 617 drawingBuffer->contextGL()->GenMailboxCHROMIUM(mailbox.name);
587 } 618 }
588 619
589 DrawingBuffer::ColorBuffer::~ColorBuffer() { 620 DrawingBuffer::ColorBuffer::~ColorBuffer() {
590 gpu::gles2::GLES2Interface* gl = drawingBuffer->contextGL(); 621 gpu::gles2::GLES2Interface* gl = drawingBuffer->contextGL();
591 if (receiveSyncToken.HasData()) 622 if (receiveSyncToken.HasData())
592 gl->WaitSyncTokenCHROMIUM(receiveSyncToken.GetConstData()); 623 gl->WaitSyncTokenCHROMIUM(receiveSyncToken.GetConstData());
593 if (imageId) { 624 if (imageId) {
594 gl->BindTexture(parameters.target, textureId); 625 gl->BindTexture(parameters.target, textureId);
595 gl->ReleaseTexImage2DCHROMIUM(parameters.target, imageId); 626 gl->ReleaseTexImage2DCHROMIUM(parameters.target, imageId);
(...skipping 151 matching lines...) Expand 10 before | Expand all | Expand 10 after
747 m_layer->clearTexture(); 778 m_layer->clearTexture();
748 779
749 m_gl->Flush(); 780 m_gl->Flush();
750 } 781 }
751 782
752 void DrawingBuffer::beginDestruction() { 783 void DrawingBuffer::beginDestruction() {
753 ASSERT(!m_destructionInProgress); 784 ASSERT(!m_destructionInProgress);
754 m_destructionInProgress = true; 785 m_destructionInProgress = true;
755 786
756 clearPlatformLayer(); 787 clearPlatformLayer();
757 m_recycledMailboxQueue.clear(); 788 m_recycledColorBufferQueue.clear();
758 789
759 if (m_multisampleFBO) 790 if (m_multisampleFBO)
760 m_gl->DeleteFramebuffers(1, &m_multisampleFBO); 791 m_gl->DeleteFramebuffers(1, &m_multisampleFBO);
761 792
762 if (m_fbo) 793 if (m_fbo)
763 m_gl->DeleteFramebuffers(1, &m_fbo); 794 m_gl->DeleteFramebuffers(1, &m_fbo);
764 795
765 if (m_multisampleRenderbuffer) 796 if (m_multisampleRenderbuffer)
766 m_gl->DeleteRenderbuffers(1, &m_multisampleRenderbuffer); 797 m_gl->DeleteRenderbuffers(1, &m_multisampleRenderbuffer);
767 798
768 if (m_depthStencilBuffer) 799 if (m_depthStencilBuffer)
769 m_gl->DeleteRenderbuffers(1, &m_depthStencilBuffer); 800 m_gl->DeleteRenderbuffers(1, &m_depthStencilBuffer);
770 801
771 m_size = IntSize(); 802 m_size = IntSize();
772 803
773 m_backColorBuffer = nullptr; 804 m_backColorBuffer = nullptr;
774 m_frontColorBuffer = nullptr; 805 m_frontColorBuffer = nullptr;
775 m_multisampleRenderbuffer = 0; 806 m_multisampleRenderbuffer = 0;
776 m_depthStencilBuffer = 0; 807 m_depthStencilBuffer = 0;
777 m_multisampleFBO = 0; 808 m_multisampleFBO = 0;
778 m_fbo = 0; 809 m_fbo = 0;
779 810
780 if (m_layer) 811 if (m_layer)
781 GraphicsLayer::unregisterContentsLayer(m_layer->layer()); 812 GraphicsLayer::unregisterContentsLayer(m_layer->layer());
782 } 813 }
783 814
784 GLuint DrawingBuffer::createColorTexture(const TextureParameters& parameters) {
785 GLuint offscreenColorTexture;
786 m_gl->GenTextures(1, &offscreenColorTexture);
787 m_gl->BindTexture(parameters.target, offscreenColorTexture);
788 m_gl->TexParameteri(parameters.target, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
789 m_gl->TexParameteri(parameters.target, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
790 m_gl->TexParameteri(parameters.target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
791 m_gl->TexParameteri(parameters.target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
792 return offscreenColorTexture;
793 }
794
795 bool DrawingBuffer::resizeDefaultFramebuffer(const IntSize& size) { 815 bool DrawingBuffer::resizeDefaultFramebuffer(const IntSize& size) {
796 // Recreate m_backColorBuffer. 816 // Recreate m_backColorBuffer.
797 m_backColorBuffer = createTextureAndAllocateMemory(size); 817 m_backColorBuffer = createColorBuffer(size);
798 818
799 attachColorBufferToReadFramebuffer(); 819 attachColorBufferToReadFramebuffer();
800 820
801 if (wantExplicitResolve()) { 821 if (wantExplicitResolve()) {
802 m_gl->BindFramebuffer(GL_FRAMEBUFFER, m_multisampleFBO); 822 m_gl->BindFramebuffer(GL_FRAMEBUFFER, m_multisampleFBO);
803 m_gl->BindRenderbuffer(GL_RENDERBUFFER, m_multisampleRenderbuffer); 823 m_gl->BindRenderbuffer(GL_RENDERBUFFER, m_multisampleRenderbuffer);
804 m_gl->RenderbufferStorageMultisampleCHROMIUM( 824 m_gl->RenderbufferStorageMultisampleCHROMIUM(
805 GL_RENDERBUFFER, m_sampleCount, getMultisampledRenderbufferFormat(), 825 GL_RENDERBUFFER, m_sampleCount, getMultisampledRenderbufferFormat(),
806 size.width(), size.height()); 826 size.width(), size.height());
807 827
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after
889 if (!resizeDefaultFramebuffer(adjustedSize)) { 909 if (!resizeDefaultFramebuffer(adjustedSize)) {
890 adjustedSize.scale(s_resourceAdjustedRatio); 910 adjustedSize.scale(s_resourceAdjustedRatio);
891 continue; 911 continue;
892 } 912 }
893 break; 913 break;
894 } while (!adjustedSize.isEmpty()); 914 } while (!adjustedSize.isEmpty());
895 915
896 m_size = adjustedSize; 916 m_size = adjustedSize;
897 // Free all mailboxes, because they are now of the wrong size. Only the 917 // Free all mailboxes, because they are now of the wrong size. Only the
898 // first call in this loop has any effect. 918 // first call in this loop has any effect.
899 m_recycledMailboxQueue.clear(); 919 m_recycledColorBufferQueue.clear();
900 m_recycledBitmaps.clear(); 920 m_recycledBitmaps.clear();
901 921
902 if (adjustedSize.isEmpty()) 922 if (adjustedSize.isEmpty())
903 return false; 923 return false;
904 } 924 }
905 925
906 m_gl->Disable(GL_SCISSOR_TEST); 926 m_gl->Disable(GL_SCISSOR_TEST);
907 m_gl->ClearColor(0, 0, 0, 927 m_gl->ClearColor(0, 0, 0,
908 defaultBufferRequiresAlphaChannelToBePreserved() ? 1 : 0); 928 defaultBufferRequiresAlphaChannelToBePreserved() ? 1 : 0);
909 m_gl->ColorMask(true, true, true, true); 929 m_gl->ColorMask(true, true, true, true);
(...skipping 176 matching lines...) Expand 10 before | Expand all | Expand 10 after
1086 pixels[i + 2] = std::min(255, pixels[i + 2] * pixels[i + 3] / 255); 1106 pixels[i + 2] = std::min(255, pixels[i + 2] * pixels[i + 3] / 255);
1087 } 1107 }
1088 } else if (op != WebGLImageConversion::AlphaDoNothing) { 1108 } else if (op != WebGLImageConversion::AlphaDoNothing) {
1089 ASSERT_NOT_REACHED(); 1109 ASSERT_NOT_REACHED();
1090 } 1110 }
1091 } 1111 }
1092 1112
1093 void DrawingBuffer::flipVertically(uint8_t* framebuffer, 1113 void DrawingBuffer::flipVertically(uint8_t* framebuffer,
1094 int width, 1114 int width,
1095 int height) { 1115 int height) {
1096 m_scanline.resize(width * 4); 1116 std::vector<uint8_t> scanline(width * 4);
erikchen 2016/10/07 16:25:09 if this gets called frequently, the new logic seem
Ken Russell (switch to Gerrit) 2016/10/07 18:34:41 This is a pretty slow path anyway. I'm personally
ccameron 2016/10/07 20:36:30 Yeah, I suspect that this was premature optimizati
1097 uint8_t* scanline = &m_scanline[0];
1098 unsigned rowBytes = width * 4; 1117 unsigned rowBytes = width * 4;
1099 unsigned count = height / 2; 1118 unsigned count = height / 2;
1100 for (unsigned i = 0; i < count; i++) { 1119 for (unsigned i = 0; i < count; i++) {
1101 uint8_t* rowA = framebuffer + i * rowBytes; 1120 uint8_t* rowA = framebuffer + i * rowBytes;
1102 uint8_t* rowB = framebuffer + (height - i - 1) * rowBytes; 1121 uint8_t* rowB = framebuffer + (height - i - 1) * rowBytes;
1103 memcpy(scanline, rowB, rowBytes); 1122 memcpy(scanline.data(), rowB, rowBytes);
1104 memcpy(rowB, rowA, rowBytes); 1123 memcpy(rowB, rowA, rowBytes);
1105 memcpy(rowA, scanline, rowBytes); 1124 memcpy(rowA, scanline.data(), rowBytes);
1106 } 1125 }
1107 } 1126 }
1108 1127
1109 void DrawingBuffer::allocateConditionallyImmutableTexture(GLenum target, 1128 RefPtr<DrawingBuffer::ColorBuffer> DrawingBuffer::createColorBuffer(
1110 GLenum internalformat, 1129 const IntSize& size) {
1111 GLsizei width, 1130 // Select the Parameters for the texture object. Allocate the backing
1112 GLsizei height, 1131 // GpuMemoryBuffer and GLImage, if one is going to be used.
1113 GLint border, 1132 ColorBufferParameters parameters;
1114 GLenum format, 1133 GLuint imageId = 0;
1115 GLenum type) { 1134 if (shouldUseChromiumImage()) {
1116 if (m_storageTextureSupported) { 1135 parameters = gpuMemoryBufferColorBufferParameters();
1117 GLenum internalStorageFormat = GL_NONE; 1136 imageId = m_gl->CreateGpuMemoryBufferImageCHROMIUM(
1118 if (internalformat == GL_RGB) { 1137 size.width(), size.height(), parameters.creationInternalColorFormat,
1119 internalStorageFormat = GL_RGB8; 1138 GC3D_SCANOUT_CHROMIUM);
1120 } else if (internalformat == GL_RGBA) { 1139 } else {
1121 internalStorageFormat = GL_RGBA8; 1140 parameters = textureColorBufferParameters();
1122 } else {
1123 NOTREACHED();
1124 }
1125 m_gl->TexStorage2DEXT(GL_TEXTURE_2D, 1, internalStorageFormat, width,
1126 height);
1127 return;
1128 } 1141 }
1129 m_gl->TexImage2D(target, 0, internalformat, width, height, border, format,
1130 type, 0);
1131 }
1132 1142
1133 void DrawingBuffer::clearChromiumImageAlpha(const ColorBuffer& info) { 1143 // Allocate the texture for this object.
1134 if (m_wantAlphaChannel) 1144 GLuint textureId = 0;
1135 return; 1145 {
1136 if (!contextProvider()->getCapabilities().chromium_image_rgb_emulation) 1146 m_gl->GenTextures(1, &textureId);
1137 return; 1147 m_gl->BindTexture(parameters.target, textureId);
1148 m_gl->TexParameteri(parameters.target, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
1149 m_gl->TexParameteri(parameters.target, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
1150 m_gl->TexParameteri(parameters.target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
1151 m_gl->TexParameteri(parameters.target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
1152 }
1138 1153
1139 GLuint fbo = 0; 1154 // If this is GpuMemoryBuffer-backed, then bind the texture to the
1140 m_gl->GenFramebuffers(1, &fbo); 1155 // GpuMemoryBuffer's GLImage. Otherwise, allocate ordinary texture storage.
1141 m_gl->BindFramebuffer(GL_FRAMEBUFFER, fbo);
1142 m_gl->FramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
1143 info.parameters.target, info.textureId, 0);
1144 m_gl->ClearColor(0, 0, 0, 1);
1145 m_gl->ColorMask(false, false, false, true);
1146 m_gl->Clear(GL_COLOR_BUFFER_BIT);
1147 m_gl->FramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
1148 info.parameters.target, 0, 0);
1149 m_gl->DeleteFramebuffers(1, &fbo);
1150 restoreFramebufferBindings();
1151 m_gl->ClearColor(m_clearColor[0], m_clearColor[1], m_clearColor[2],
1152 m_clearColor[3]);
1153 m_gl->ColorMask(m_colorMask[0], m_colorMask[1], m_colorMask[2],
1154 m_colorMask[3]);
1155 }
1156
1157 RefPtr<DrawingBuffer::ColorBuffer>
1158 DrawingBuffer::createTextureAndAllocateMemory(const IntSize& size) {
1159 if (!shouldUseChromiumImage())
1160 return createDefaultTextureAndAllocateMemory(size);
1161
1162 TextureParameters parameters = chromiumImageTextureParameters();
1163 GLuint imageId = m_gl->CreateGpuMemoryBufferImageCHROMIUM(
1164 size.width(), size.height(), parameters.creationInternalColorFormat,
1165 GC3D_SCANOUT_CHROMIUM);
1166 GLuint textureId = createColorTexture(parameters);
1167 if (imageId) { 1156 if (imageId) {
1168 m_gl->BindTexImage2DCHROMIUM(parameters.target, imageId); 1157 m_gl->BindTexImage2DCHROMIUM(parameters.target, imageId);
1158 } else {
1159 if (m_storageTextureSupported) {
1160 GLenum internalStorageFormat = GL_NONE;
1161 if (parameters.creationInternalColorFormat == GL_RGB) {
1162 internalStorageFormat = GL_RGB8;
1163 } else if (parameters.creationInternalColorFormat == GL_RGBA) {
1164 internalStorageFormat = GL_RGBA8;
1165 } else {
1166 NOTREACHED();
1167 }
1168 m_gl->TexStorage2DEXT(GL_TEXTURE_2D, 1, internalStorageFormat,
1169 size.width(), size.height());
1170 } else {
1171 m_gl->TexImage2D(parameters.target, 0,
1172 parameters.creationInternalColorFormat, size.width(),
1173 size.height(), 0, parameters.colorFormat,
1174 GL_UNSIGNED_BYTE, 0);
1175 }
1169 } 1176 }
1170 1177
1171 RefPtr<ColorBuffer> info(adoptRef(new ColorBuffer(this, parameters, size))); 1178 // Clear the alpha channel if this is RGB emulated.
1172 info->textureId = textureId; 1179 if (imageId && !m_wantAlphaChannel &&
1173 info->imageId = imageId; 1180 contextProvider()->getCapabilities().chromium_image_rgb_emulation) {
1174 clearChromiumImageAlpha(*info); 1181 GLuint fbo = 0;
1175 return info; 1182 m_gl->GenFramebuffers(1, &fbo);
1176 } 1183 m_gl->BindFramebuffer(GL_FRAMEBUFFER, fbo);
1184 m_gl->FramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
1185 parameters.target, textureId, 0);
1186 m_gl->ClearColor(0, 0, 0, 1);
1187 m_gl->ColorMask(false, false, false, true);
1188 m_gl->Clear(GL_COLOR_BUFFER_BIT);
1189 m_gl->FramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
1190 parameters.target, 0, 0);
1191 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 }
1177 1198
1178 RefPtr<DrawingBuffer::ColorBuffer> 1199 return adoptRef(new ColorBuffer(this, parameters, size, textureId, imageId));
1179 DrawingBuffer::createDefaultTextureAndAllocateMemory(const IntSize& size) {
1180 TextureParameters parameters = defaultTextureParameters();
1181 RefPtr<ColorBuffer> info(adoptRef(new ColorBuffer(this, parameters, size)));
1182 info->textureId = createColorTexture(parameters);
1183 allocateConditionallyImmutableTexture(
1184 parameters.target, parameters.creationInternalColorFormat, size.width(),
1185 size.height(), 0, parameters.colorFormat, GL_UNSIGNED_BYTE);
1186 return info;
1187 } 1200 }
1188 1201
1189 void DrawingBuffer::attachColorBufferToReadFramebuffer() { 1202 void DrawingBuffer::attachColorBufferToReadFramebuffer() {
1190 m_gl->BindFramebuffer(GL_FRAMEBUFFER, m_fbo); 1203 m_gl->BindFramebuffer(GL_FRAMEBUFFER, m_fbo);
1191 1204
1192 GLenum target = m_backColorBuffer->parameters.target; 1205 GLenum target = m_backColorBuffer->parameters.target;
1193 GLenum id = m_backColorBuffer->textureId; 1206 GLenum id = m_backColorBuffer->textureId;
1194 1207
1195 m_gl->BindTexture(target, id); 1208 m_gl->BindTexture(target, id);
1196 1209
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
1233 // the public interface for WebGL does not support GL_TEXTURE_RECTANGLE. 1246 // the public interface for WebGL does not support GL_TEXTURE_RECTANGLE.
1234 m_gl->BindTexture(GL_TEXTURE_2D, m_texture2DBinding); 1247 m_gl->BindTexture(GL_TEXTURE_2D, m_texture2DBinding);
1235 } 1248 }
1236 1249
1237 bool DrawingBuffer::shouldUseChromiumImage() { 1250 bool DrawingBuffer::shouldUseChromiumImage() {
1238 return RuntimeEnabledFeatures::webGLImageChromiumEnabled() && 1251 return RuntimeEnabledFeatures::webGLImageChromiumEnabled() &&
1239 m_chromiumImageUsage == AllowChromiumImage; 1252 m_chromiumImageUsage == AllowChromiumImage;
1240 } 1253 }
1241 1254
1242 } // namespace blink 1255 } // namespace blink
OLDNEW
« no previous file with comments | « third_party/WebKit/Source/platform/graphics/gpu/DrawingBuffer.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698