OLD | NEW |
1 // Copyright 2010 The Chromium Authors. All rights reserved. | 1 // Copyright 2010 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "config.h" | 5 #include "config.h" |
6 | 6 |
7 #include "cc/gl_renderer.h" | 7 #include "cc/gl_renderer.h" |
8 | 8 |
9 #include "base/debug/trace_event.h" | 9 #include "base/debug/trace_event.h" |
10 #include "base/logging.h" | 10 #include "base/logging.h" |
(...skipping 385 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
396 platformTextureDescription.fWidth = sourceTexture->size().width(); | 396 platformTextureDescription.fWidth = sourceTexture->size().width(); |
397 platformTextureDescription.fHeight = sourceTexture->size().height(); | 397 platformTextureDescription.fHeight = sourceTexture->size().height(); |
398 platformTextureDescription.fConfig = kSkia8888_GrPixelConfig; | 398 platformTextureDescription.fConfig = kSkia8888_GrPixelConfig; |
399 platformTextureDescription.fTextureHandle = lock.textureId(); | 399 platformTextureDescription.fTextureHandle = lock.textureId(); |
400 SkAutoTUnref<GrTexture> texture(grContext->createPlatformTexture(platformTex
tureDescription)); | 400 SkAutoTUnref<GrTexture> texture(grContext->createPlatformTexture(platformTex
tureDescription)); |
401 | 401 |
402 // Place the platform texture inside an SkBitmap. | 402 // Place the platform texture inside an SkBitmap. |
403 SkBitmap source; | 403 SkBitmap source; |
404 source.setConfig(SkBitmap::kARGB_8888_Config, sourceTexture->size().width(),
sourceTexture->size().height()); | 404 source.setConfig(SkBitmap::kARGB_8888_Config, sourceTexture->size().width(),
sourceTexture->size().height()); |
405 source.setPixelRef(new SkGrPixelRef(texture.get()))->unref(); | 405 source.setPixelRef(new SkGrPixelRef(texture.get()))->unref(); |
406 | 406 |
407 // Create a scratch texture for backing store. | 407 // Create a scratch texture for backing store. |
408 GrTextureDesc desc; | 408 GrTextureDesc desc; |
409 desc.fFlags = kRenderTarget_GrTextureFlagBit | kNoStencil_GrTextureFlagBit; | 409 desc.fFlags = kRenderTarget_GrTextureFlagBit | kNoStencil_GrTextureFlagBit; |
410 desc.fSampleCnt = 0; | 410 desc.fSampleCnt = 0; |
411 desc.fWidth = source.width(); | 411 desc.fWidth = source.width(); |
412 desc.fHeight = source.height(); | 412 desc.fHeight = source.height(); |
413 desc.fConfig = kSkia8888_GrPixelConfig; | 413 desc.fConfig = kSkia8888_GrPixelConfig; |
414 GrAutoScratchTexture scratchTexture(grContext, desc, GrContext::kExact_Scrat
chTexMatch); | 414 GrAutoScratchTexture scratchTexture(grContext, desc, GrContext::kExact_Scrat
chTexMatch); |
415 SkAutoTUnref<GrTexture> backingStore(scratchTexture.detach()); | 415 SkAutoTUnref<GrTexture> backingStore(scratchTexture.detach()); |
416 | 416 |
417 // Create a device and canvas using that backing store. | 417 // Create a device and canvas using that backing store. |
418 SkGpuDevice device(grContext, backingStore.get()); | 418 SkGpuDevice device(grContext, backingStore.get()); |
419 SkCanvas canvas(&device); | 419 SkCanvas canvas(&device); |
420 | 420 |
421 // Draw the source bitmap through the filter to the canvas. | 421 // Draw the source bitmap through the filter to the canvas. |
422 SkPaint paint; | 422 SkPaint paint; |
423 paint.setImageFilter(filter); | 423 paint.setImageFilter(filter); |
424 canvas.clear(0x0); | 424 canvas.clear(0x0); |
425 canvas.drawSprite(source, 0, 0, &paint); | 425 canvas.drawSprite(source, 0, 0, &paint); |
426 canvas.flush(); | 426 canvas.flush(); |
427 context3d->flush(); | 427 context3d->flush(); |
428 return device.accessBitmap(false); | 428 return device.accessBitmap(false); |
429 } | 429 } |
430 | 430 |
431 scoped_ptr<ScopedTexture> GLRenderer::drawBackgroundFilters(DrawingFrame& frame,
const RenderPassDrawQuad* quad, const WebKit::WebFilterOperations& filters, con
st WebTransformationMatrix& contentsDeviceTransform) | 431 scoped_ptr<ScopedTexture> GLRenderer::drawBackgroundFilters( |
| 432 DrawingFrame& frame, const RenderPassDrawQuad* quad, |
| 433 const WebKit::WebFilterOperations& filters, |
| 434 const WebTransformationMatrix& contentsDeviceTransform, |
| 435 const WebTransformationMatrix& contentsDeviceTransformInverse) |
432 { | 436 { |
433 // This method draws a background filter, which applies a filter to any pixe
ls behind the quad and seen through its background. | 437 // This method draws a background filter, which applies a filter to any pixe
ls behind the quad and seen through its background. |
434 // The algorithm works as follows: | 438 // The algorithm works as follows: |
435 // 1. Compute a bounding box around the pixels that will be visible through
the quad. | 439 // 1. Compute a bounding box around the pixels that will be visible through
the quad. |
436 // 2. Read the pixels in the bounding box into a buffer R. | 440 // 2. Read the pixels in the bounding box into a buffer R. |
437 // 3. Apply the background filter to R, so that it is applied in the pixels'
coordinate space. | 441 // 3. Apply the background filter to R, so that it is applied in the pixels'
coordinate space. |
438 // 4. Apply the quad's inverse transform to map the pixels in R into the qua
d's content space. This implicitly | 442 // 4. Apply the quad's inverse transform to map the pixels in R into the qua
d's content space. This implicitly |
439 // clips R by the content bounds of the quad since the destination texture h
as bounds matching the quad's content. | 443 // clips R by the content bounds of the quad since the destination texture h
as bounds matching the quad's content. |
440 // 5. Draw the background texture for the contents using the same transform
as used to draw the contents itself. This is done | 444 // 5. Draw the background texture for the contents using the same transform
as used to draw the contents itself. This is done |
441 // without blending to replace the current background pixels with the new fi
ltered background. | 445 // without blending to replace the current background pixels with the new fi
ltered background. |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
480 return scoped_ptr<ScopedTexture>(); | 484 return scoped_ptr<ScopedTexture>(); |
481 | 485 |
482 const RenderPass* targetRenderPass = frame.currentRenderPass; | 486 const RenderPass* targetRenderPass = frame.currentRenderPass; |
483 bool usingBackgroundTexture = useScopedTexture(frame, backgroundTexture.get(
), quad->quadRect()); | 487 bool usingBackgroundTexture = useScopedTexture(frame, backgroundTexture.get(
), quad->quadRect()); |
484 | 488 |
485 if (usingBackgroundTexture) { | 489 if (usingBackgroundTexture) { |
486 // Copy the readback pixels from device to the background texture for th
e surface. | 490 // Copy the readback pixels from device to the background texture for th
e surface. |
487 WebTransformationMatrix deviceToFramebufferTransform; | 491 WebTransformationMatrix deviceToFramebufferTransform; |
488 deviceToFramebufferTransform.translate(quad->quadRect().width() / 2.0, q
uad->quadRect().height() / 2.0); | 492 deviceToFramebufferTransform.translate(quad->quadRect().width() / 2.0, q
uad->quadRect().height() / 2.0); |
489 deviceToFramebufferTransform.scale3d(quad->quadRect().width(), quad->qua
dRect().height(), 1); | 493 deviceToFramebufferTransform.scale3d(quad->quadRect().width(), quad->qua
dRect().height(), 1); |
490 deviceToFramebufferTransform.multiply(contentsDeviceTransform.inverse())
; | 494 deviceToFramebufferTransform.multiply(contentsDeviceTransformInverse); |
491 copyTextureToFramebuffer(frame, filteredDeviceBackgroundTextureId, devic
eRect, deviceToFramebufferTransform); | 495 copyTextureToFramebuffer(frame, filteredDeviceBackgroundTextureId, devic
eRect, deviceToFramebufferTransform); |
492 } | 496 } |
493 | 497 |
494 useRenderPass(frame, targetRenderPass); | 498 useRenderPass(frame, targetRenderPass); |
495 | 499 |
496 if (!usingBackgroundTexture) | 500 if (!usingBackgroundTexture) |
497 return scoped_ptr<ScopedTexture>(); | 501 return scoped_ptr<ScopedTexture>(); |
498 return backgroundTexture.Pass(); | 502 return backgroundTexture.Pass(); |
499 } | 503 } |
500 | 504 |
501 void GLRenderer::drawRenderPassQuad(DrawingFrame& frame, const RenderPassDrawQua
d* quad) | 505 void GLRenderer::drawRenderPassQuad(DrawingFrame& frame, const RenderPassDrawQua
d* quad) |
502 { | 506 { |
503 CachedTexture* contentsTexture = m_renderPassTextures.get(quad->renderPassId
()); | 507 CachedTexture* contentsTexture = m_renderPassTextures.get(quad->renderPassId
()); |
504 if (!contentsTexture || !contentsTexture->id()) | 508 if (!contentsTexture || !contentsTexture->id()) |
505 return; | 509 return; |
506 | 510 |
507 const RenderPass* renderPass = frame.renderPassesById->get(quad->renderPassI
d()); | 511 const RenderPass* renderPass = frame.renderPassesById->get(quad->renderPassI
d()); |
508 DCHECK(renderPass); | 512 DCHECK(renderPass); |
509 if (!renderPass) | 513 if (!renderPass) |
510 return; | 514 return; |
511 | 515 |
512 WebTransformationMatrix quadRectMatrix; | 516 WebTransformationMatrix quadRectMatrix; |
513 quadRectTransform(&quadRectMatrix, quad->quadTransform(), quad->quadRect()); | 517 quadRectTransform(&quadRectMatrix, quad->quadTransform(), quad->quadRect()); |
514 WebTransformationMatrix contentsDeviceTransform = (frame.windowMatrix * fram
e.projectionMatrix * quadRectMatrix).to2dTransform(); | 518 WebTransformationMatrix contentsDeviceTransform = (frame.windowMatrix * fram
e.projectionMatrix * quadRectMatrix).to2dTransform(); |
515 | 519 |
516 // Can only draw surface if device matrix is invertible. | 520 // Can only draw surface if device matrix is invertible. |
517 if (!contentsDeviceTransform.isInvertible()) | 521 if (!contentsDeviceTransform.isInvertible()) |
518 return; | 522 return; |
519 | 523 |
520 scoped_ptr<ScopedTexture> backgroundTexture = drawBackgroundFilters(frame, q
uad, renderPass->backgroundFilters(), contentsDeviceTransform); | 524 WebTransformationMatrix contentsDeviceTransformInverse = contentsDeviceTrans
form.inverse(); |
| 525 scoped_ptr<ScopedTexture> backgroundTexture = drawBackgroundFilters( |
| 526 frame, quad, renderPass->backgroundFilters(), |
| 527 contentsDeviceTransform, contentsDeviceTransformInverse); |
521 | 528 |
522 // FIXME: Cache this value so that we don't have to do it for both the surfa
ce and its replica. | 529 // FIXME: Cache this value so that we don't have to do it for both the surfa
ce and its replica. |
523 // Apply filters to the contents texture. | 530 // Apply filters to the contents texture. |
524 SkBitmap filterBitmap; | 531 SkBitmap filterBitmap; |
525 if (renderPass->filter()) { | 532 if (renderPass->filter()) { |
526 filterBitmap = applyImageFilter(this, renderPass->filter(), contentsText
ure); | 533 filterBitmap = applyImageFilter(this, renderPass->filter(), contentsText
ure); |
527 } else { | 534 } else { |
528 filterBitmap = applyFilters(this, renderPass->filters(), contentsTexture
); | 535 filterBitmap = applyFilters(this, renderPass->filters(), contentsTexture
); |
529 } | 536 } |
530 scoped_ptr<ResourceProvider::ScopedReadLockGL> contentsResourceLock; | 537 scoped_ptr<ResourceProvider::ScopedReadLockGL> contentsResourceLock; |
(...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
628 } | 635 } |
629 | 636 |
630 if (shaderEdgeLocation != -1) { | 637 if (shaderEdgeLocation != -1) { |
631 float edge[24]; | 638 float edge[24]; |
632 deviceLayerEdges.toFloatArray(edge); | 639 deviceLayerEdges.toFloatArray(edge); |
633 deviceLayerBounds.toFloatArray(&edge[12]); | 640 deviceLayerBounds.toFloatArray(&edge[12]); |
634 GLC(context(), context()->uniform3fv(shaderEdgeLocation, 8, edge)); | 641 GLC(context(), context()->uniform3fv(shaderEdgeLocation, 8, edge)); |
635 } | 642 } |
636 | 643 |
637 // Map device space quad to surface space. contentsDeviceTransform has no 3d
component since it was generated with to2dTransform() so we don't need to proje
ct. | 644 // Map device space quad to surface space. contentsDeviceTransform has no 3d
component since it was generated with to2dTransform() so we don't need to proje
ct. |
638 gfx::QuadF surfaceQuad = MathUtil::mapQuad(contentsDeviceTransform.inverse()
, deviceLayerEdges.ToQuadF(), clipped); | 645 gfx::QuadF surfaceQuad = MathUtil::mapQuad(contentsDeviceTransformInverse, d
eviceLayerEdges.ToQuadF(), clipped); |
639 DCHECK(!clipped); | 646 DCHECK(!clipped); |
640 | 647 |
641 setShaderOpacity(quad->opacity(), shaderAlphaLocation); | 648 setShaderOpacity(quad->opacity(), shaderAlphaLocation); |
642 setShaderQuadF(surfaceQuad, shaderQuadLocation); | 649 setShaderQuadF(surfaceQuad, shaderQuadLocation); |
643 drawQuadGeometry(frame, quad->quadTransform(), quad->quadRect(), shaderMatri
xLocation); | 650 drawQuadGeometry(frame, quad->quadTransform(), quad->quadRect(), shaderMatri
xLocation); |
644 } | 651 } |
645 | 652 |
646 void GLRenderer::drawSolidColorQuad(const DrawingFrame& frame, const SolidColorD
rawQuad* quad) | 653 void GLRenderer::drawSolidColorQuad(const DrawingFrame& frame, const SolidColorD
rawQuad* quad) |
647 { | 654 { |
648 const SolidColorProgram* program = solidColorProgram(); | 655 const SolidColorProgram* program = solidColorProgram(); |
(...skipping 152 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
801 | 808 |
802 float sign = gfx::QuadF(tileRect).IsCounterClockwise() ? -1 : 1; | 809 float sign = gfx::QuadF(tileRect).IsCounterClockwise() ? -1 : 1; |
803 bottomEdge.scale(sign); | 810 bottomEdge.scale(sign); |
804 leftEdge.scale(sign); | 811 leftEdge.scale(sign); |
805 topEdge.scale(sign); | 812 topEdge.scale(sign); |
806 rightEdge.scale(sign); | 813 rightEdge.scale(sign); |
807 | 814 |
808 // Create device space quad. | 815 // Create device space quad. |
809 LayerQuad deviceQuad(leftEdge, topEdge, rightEdge, bottomEdge); | 816 LayerQuad deviceQuad(leftEdge, topEdge, rightEdge, bottomEdge); |
810 | 817 |
811 // Map device space quad to local space. contentsDeviceTransform has no
3d component since it was generated with to2dTransform() so we don't need to pro
ject. | 818 // Map device space quad to local space. deviceTransform has no 3d compo
nent since it was generated with to2dTransform() so we don't need to project. |
812 WebTransformationMatrix inverseDeviceTransform = deviceTransform.inverse
(); | 819 WebTransformationMatrix deviceTransformInverse = deviceTransform.inverse
(); |
813 localQuad = MathUtil::mapQuad(inverseDeviceTransform, deviceQuad.ToQuadF
(), clipped); | 820 localQuad = MathUtil::mapQuad(deviceTransformInverse, deviceQuad.ToQuadF
(), clipped); |
814 | 821 |
815 // We should not DCHECK(!clipped) here, because anti-aliasing inflation
may cause deviceQuad to become | 822 // We should not DCHECK(!clipped) here, because anti-aliasing inflation
may cause deviceQuad to become |
816 // clipped. To our knowledge this scenario does not need to be handled d
ifferently than the unclipped case. | 823 // clipped. To our knowledge this scenario does not need to be handled d
ifferently than the unclipped case. |
817 } else { | 824 } else { |
818 // Move fragment shader transform to vertex shader. We can do this while | 825 // Move fragment shader transform to vertex shader. We can do this while |
819 // still producing correct results as fragmentTexTransformLocation | 826 // still producing correct results as fragmentTexTransformLocation |
820 // should always be non-negative when tiles are transformed in a way | 827 // should always be non-negative when tiles are transformed in a way |
821 // that could result in sampling outside the layer. | 828 // that could result in sampling outside the layer. |
822 vertexTexScaleX *= fragmentTexScaleX; | 829 vertexTexScaleX *= fragmentTexScaleX; |
823 vertexTexScaleY *= fragmentTexScaleY; | 830 vertexTexScaleY *= fragmentTexScaleY; |
(...skipping 801 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1625 | 1632 |
1626 releaseRenderPassTextures(); | 1633 releaseRenderPassTextures(); |
1627 } | 1634 } |
1628 | 1635 |
1629 bool GLRenderer::isContextLost() | 1636 bool GLRenderer::isContextLost() |
1630 { | 1637 { |
1631 return (m_context->getGraphicsResetStatusARB() != GL_NO_ERROR); | 1638 return (m_context->getGraphicsResetStatusARB() != GL_NO_ERROR); |
1632 } | 1639 } |
1633 | 1640 |
1634 } // namespace cc | 1641 } // namespace cc |
OLD | NEW |