Chromium Code Reviews| OLD | NEW |
|---|---|
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 |
| OLD | NEW |