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

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

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