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 "FloatQuad.h" | 9 #include "FloatQuad.h" |
10 #include "NotImplemented.h" | 10 #include "NotImplemented.h" |
(...skipping 448 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
459 // FIXME: Do a single readback for both the surface and replica and cache th
e filtered results (once filter textures are not reused). | 459 // FIXME: Do a single readback for both the surface and replica and cache th
e filtered results (once filter textures are not reused). |
460 gfx::Rect deviceRect = gfx::ToEnclosingRect(MathUtil::mapClippedRect(content
sDeviceTransform, cc::FloatRect(sharedGeometryQuad().boundingBox()))); | 460 gfx::Rect deviceRect = gfx::ToEnclosingRect(MathUtil::mapClippedRect(content
sDeviceTransform, cc::FloatRect(sharedGeometryQuad().boundingBox()))); |
461 | 461 |
462 int top, right, bottom, left; | 462 int top, right, bottom, left; |
463 filters.getOutsets(top, right, bottom, left); | 463 filters.getOutsets(top, right, bottom, left); |
464 deviceRect.Inset(-left, -top, -right, -bottom); | 464 deviceRect.Inset(-left, -top, -right, -bottom); |
465 | 465 |
466 deviceRect.Intersect(frame.currentRenderPass->outputRect()); | 466 deviceRect.Intersect(frame.currentRenderPass->outputRect()); |
467 | 467 |
468 scoped_ptr<ScopedTexture> deviceBackgroundTexture = ScopedTexture::create(m_
resourceProvider); | 468 scoped_ptr<ScopedTexture> deviceBackgroundTexture = ScopedTexture::create(m_
resourceProvider); |
469 if (!getFramebufferTexture(deviceBackgroundTexture.get(), cc::IntRect(device
Rect))) | 469 if (!getFramebufferTexture(deviceBackgroundTexture.get(), deviceRect)) |
470 return scoped_ptr<ScopedTexture>(); | 470 return scoped_ptr<ScopedTexture>(); |
471 | 471 |
472 SkBitmap filteredDeviceBackground = applyFilters(this, filters, deviceBackgr
oundTexture.get()); | 472 SkBitmap filteredDeviceBackground = applyFilters(this, filters, deviceBackgr
oundTexture.get()); |
473 if (!filteredDeviceBackground.getTexture()) | 473 if (!filteredDeviceBackground.getTexture()) |
474 return scoped_ptr<ScopedTexture>(); | 474 return scoped_ptr<ScopedTexture>(); |
475 | 475 |
476 GrTexture* texture = reinterpret_cast<GrTexture*>(filteredDeviceBackground.g
etTexture()); | 476 GrTexture* texture = reinterpret_cast<GrTexture*>(filteredDeviceBackground.g
etTexture()); |
477 int filteredDeviceBackgroundTextureId = texture->getTextureHandle(); | 477 int filteredDeviceBackgroundTextureId = texture->getTextureHandle(); |
478 | 478 |
479 scoped_ptr<ScopedTexture> backgroundTexture = ScopedTexture::create(m_resour
ceProvider); | 479 scoped_ptr<ScopedTexture> backgroundTexture = ScopedTexture::create(m_resour
ceProvider); |
(...skipping 212 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
692 // by deflating the tile region half a texel or half a texel | 692 // by deflating the tile region half a texel or half a texel |
693 // minus epsilon for one pixel layers. The resulting clamp region | 693 // minus epsilon for one pixel layers. The resulting clamp region |
694 // is mapped to the unit square by the vertex shader and mapped | 694 // is mapped to the unit square by the vertex shader and mapped |
695 // back to normalized texture coordinates by the fragment shader | 695 // back to normalized texture coordinates by the fragment shader |
696 // after being clamped to 0-1 range. | 696 // after being clamped to 0-1 range. |
697 const float epsilon = 1 / 1024.0f; | 697 const float epsilon = 1 / 1024.0f; |
698 float clampX = min(0.5, clampRect.width() / 2.0 - epsilon); | 698 float clampX = min(0.5, clampRect.width() / 2.0 - epsilon); |
699 float clampY = min(0.5, clampRect.height() / 2.0 - epsilon); | 699 float clampY = min(0.5, clampRect.height() / 2.0 - epsilon); |
700 clampRect.Inset(clampX, clampY, clampX, clampY); | 700 clampRect.Inset(clampX, clampY, clampX, clampY); |
701 | 701 |
702 gfx::PointF textureOffset = quad->textureOffset() + clampRect.OffsetFromOrig
in() - quad->quadRect().OffsetFromOrigin(); | 702 gfx::Vector2dF textureOffset = quad->textureOffset() + clampRect.OffsetFromO
rigin() - quad->quadRect().OffsetFromOrigin(); |
703 | 703 |
704 // Map clamping rectangle to unit square. | 704 // Map clamping rectangle to unit square. |
705 float vertexTexTranslateX = -clampRect.x() / clampRect.width(); | 705 float vertexTexTranslateX = -clampRect.x() / clampRect.width(); |
706 float vertexTexTranslateY = -clampRect.y() / clampRect.height(); | 706 float vertexTexTranslateY = -clampRect.y() / clampRect.height(); |
707 float vertexTexScaleX = tileRect.width() / clampRect.width(); | 707 float vertexTexScaleX = tileRect.width() / clampRect.width(); |
708 float vertexTexScaleY = tileRect.height() / clampRect.height(); | 708 float vertexTexScaleY = tileRect.height() / clampRect.height(); |
709 | 709 |
710 // Map to normalized texture coordinates. | 710 // Map to normalized texture coordinates. |
711 const gfx::Size& textureSize = quad->textureSize(); | 711 const gfx::Size& textureSize = quad->textureSize(); |
712 float fragmentTexTranslateX = textureOffset.x() / textureSize.width(); | 712 float fragmentTexTranslateX = textureOffset.x() / textureSize.width(); |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
763 deviceLayerEdges.inflateAntiAliasingDistance(); | 763 deviceLayerEdges.inflateAntiAliasingDistance(); |
764 | 764 |
765 float edge[24]; | 765 float edge[24]; |
766 deviceLayerEdges.toFloatArray(edge); | 766 deviceLayerEdges.toFloatArray(edge); |
767 deviceLayerBounds.toFloatArray(&edge[12]); | 767 deviceLayerBounds.toFloatArray(&edge[12]); |
768 GLC(context(), context()->uniform3fv(uniforms.edgeLocation, 8, edge)); | 768 GLC(context(), context()->uniform3fv(uniforms.edgeLocation, 8, edge)); |
769 | 769 |
770 GLC(context(), context()->uniform4f(uniforms.vertexTexTransformLocation,
vertexTexTranslateX, vertexTexTranslateY, vertexTexScaleX, vertexTexScaleY)); | 770 GLC(context(), context()->uniform4f(uniforms.vertexTexTransformLocation,
vertexTexTranslateX, vertexTexTranslateY, vertexTexScaleX, vertexTexScaleY)); |
771 GLC(context(), context()->uniform4f(uniforms.fragmentTexTransformLocatio
n, fragmentTexTranslateX, fragmentTexTranslateY, fragmentTexScaleX, fragmentTexS
caleY)); | 771 GLC(context(), context()->uniform4f(uniforms.fragmentTexTransformLocatio
n, fragmentTexTranslateX, fragmentTexTranslateY, fragmentTexScaleX, fragmentTexS
caleY)); |
772 | 772 |
773 FloatPoint bottomRight(tileRect.right(), tileRect.bottom()); | 773 gfx::PointF bottomRight(tileRect.right(), tileRect.bottom()); |
774 FloatPoint bottomLeft(tileRect.x(), tileRect.bottom()); | 774 gfx::PointF bottomLeft(tileRect.x(), tileRect.bottom()); |
775 FloatPoint topLeft(tileRect.x(), tileRect.y()); | 775 gfx::PointF topLeft(tileRect.x(), tileRect.y()); |
776 FloatPoint topRight(tileRect.right(), tileRect.y()); | 776 gfx::PointF topRight(tileRect.right(), tileRect.y()); |
777 | 777 |
778 // Map points to device space. | 778 // Map points to device space. |
779 bottomRight = MathUtil::mapPoint(deviceTransform, bottomRight, clipped); | 779 bottomRight = MathUtil::mapPoint(deviceTransform, bottomRight, clipped); |
780 DCHECK(!clipped); | 780 DCHECK(!clipped); |
781 bottomLeft = MathUtil::mapPoint(deviceTransform, bottomLeft, clipped); | 781 bottomLeft = MathUtil::mapPoint(deviceTransform, bottomLeft, clipped); |
782 DCHECK(!clipped); | 782 DCHECK(!clipped); |
783 topLeft = MathUtil::mapPoint(deviceTransform, topLeft, clipped); | 783 topLeft = MathUtil::mapPoint(deviceTransform, topLeft, clipped); |
784 DCHECK(!clipped); | 784 DCHECK(!clipped); |
785 topRight = MathUtil::mapPoint(deviceTransform, topRight, clipped); | 785 topRight = MathUtil::mapPoint(deviceTransform, topRight, clipped); |
786 DCHECK(!clipped); | 786 DCHECK(!clipped); |
(...skipping 443 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1230 m_context->ensureFramebufferCHROMIUM(); | 1230 m_context->ensureFramebufferCHROMIUM(); |
1231 m_isFramebufferDiscarded = false; | 1231 m_isFramebufferDiscarded = false; |
1232 } | 1232 } |
1233 | 1233 |
1234 void GLRenderer::onContextLost() | 1234 void GLRenderer::onContextLost() |
1235 { | 1235 { |
1236 m_client->didLoseContext(); | 1236 m_client->didLoseContext(); |
1237 } | 1237 } |
1238 | 1238 |
1239 | 1239 |
1240 void GLRenderer::getFramebufferPixels(void *pixels, const IntRect& rect) | 1240 void GLRenderer::getFramebufferPixels(void *pixels, const gfx::Rect& rect) |
1241 { | 1241 { |
1242 DCHECK(rect.maxX() <= viewportWidth()); | 1242 DCHECK(rect.right() <= viewportWidth()); |
1243 DCHECK(rect.maxY() <= viewportHeight()); | 1243 DCHECK(rect.bottom() <= viewportHeight()); |
1244 | 1244 |
1245 if (!pixels) | 1245 if (!pixels) |
1246 return; | 1246 return; |
1247 | 1247 |
1248 makeContextCurrent(); | 1248 makeContextCurrent(); |
1249 | 1249 |
1250 bool doWorkaround = needsIOSurfaceReadbackWorkaround(); | 1250 bool doWorkaround = needsIOSurfaceReadbackWorkaround(); |
1251 | 1251 |
1252 GLuint temporaryTexture = 0; | 1252 GLuint temporaryTexture = 0; |
1253 GLuint temporaryFBO = 0; | 1253 GLuint temporaryFBO = 0; |
(...skipping 14 matching lines...) Expand all Loading... |
1268 GLC(m_context, m_context->copyTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 0, 0
, viewportSize().width(), viewportSize().height(), 0)); | 1268 GLC(m_context, m_context->copyTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 0, 0
, viewportSize().width(), viewportSize().height(), 0)); |
1269 temporaryFBO = m_context->createFramebuffer(); | 1269 temporaryFBO = m_context->createFramebuffer(); |
1270 // Attach this texture to an FBO, and perform the readback from that FBO
. | 1270 // Attach this texture to an FBO, and perform the readback from that FBO
. |
1271 GLC(m_context, m_context->bindFramebuffer(GL_FRAMEBUFFER, temporaryFBO))
; | 1271 GLC(m_context, m_context->bindFramebuffer(GL_FRAMEBUFFER, temporaryFBO))
; |
1272 GLC(m_context, m_context->framebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_
ATTACHMENT0, GL_TEXTURE_2D, temporaryTexture, 0)); | 1272 GLC(m_context, m_context->framebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_
ATTACHMENT0, GL_TEXTURE_2D, temporaryTexture, 0)); |
1273 | 1273 |
1274 DCHECK(m_context->checkFramebufferStatus(GL_FRAMEBUFFER) == GL_FRAMEBUFF
ER_COMPLETE); | 1274 DCHECK(m_context->checkFramebufferStatus(GL_FRAMEBUFFER) == GL_FRAMEBUFF
ER_COMPLETE); |
1275 } | 1275 } |
1276 | 1276 |
1277 scoped_array<uint8_t> srcPixels(new uint8_t[rect.width() * rect.height() * 4
]); | 1277 scoped_array<uint8_t> srcPixels(new uint8_t[rect.width() * rect.height() * 4
]); |
1278 GLC(m_context, m_context->readPixels(rect.x(), viewportSize().height() - rec
t.maxY(), rect.width(), rect.height(), | 1278 GLC(m_context, m_context->readPixels(rect.x(), viewportSize().height() - rec
t.bottom(), rect.width(), rect.height(), |
1279 GL_RGBA, GL_UNSIGNED_BYTE, srcPixels.get())
); | 1279 GL_RGBA, GL_UNSIGNED_BYTE, srcPixels.ge
t())); |
1280 | 1280 |
1281 uint8_t* destPixels = static_cast<uint8_t*>(pixels); | 1281 uint8_t* destPixels = static_cast<uint8_t*>(pixels); |
1282 size_t rowBytes = rect.width() * 4; | 1282 size_t rowBytes = rect.width() * 4; |
1283 int numRows = rect.height(); | 1283 int numRows = rect.height(); |
1284 size_t totalBytes = numRows * rowBytes; | 1284 size_t totalBytes = numRows * rowBytes; |
1285 for (size_t destY = 0; destY < totalBytes; destY += rowBytes) { | 1285 for (size_t destY = 0; destY < totalBytes; destY += rowBytes) { |
1286 // Flip Y axis. | 1286 // Flip Y axis. |
1287 size_t srcY = totalBytes - destY - rowBytes; | 1287 size_t srcY = totalBytes - destY - rowBytes; |
1288 // Swizzle BGRA -> RGBA. | 1288 // Swizzle BGRA -> RGBA. |
1289 for (size_t x = 0; x < rowBytes; x += 4) { | 1289 for (size_t x = 0; x < rowBytes; x += 4) { |
1290 destPixels[destY + (x+0)] = srcPixels.get()[srcY + (x+2)]; | 1290 destPixels[destY + (x+0)] = srcPixels.get()[srcY + (x+2)]; |
1291 destPixels[destY + (x+1)] = srcPixels.get()[srcY + (x+1)]; | 1291 destPixels[destY + (x+1)] = srcPixels.get()[srcY + (x+1)]; |
1292 destPixels[destY + (x+2)] = srcPixels.get()[srcY + (x+0)]; | 1292 destPixels[destY + (x+2)] = srcPixels.get()[srcY + (x+0)]; |
1293 destPixels[destY + (x+3)] = srcPixels.get()[srcY + (x+3)]; | 1293 destPixels[destY + (x+3)] = srcPixels.get()[srcY + (x+3)]; |
1294 } | 1294 } |
1295 } | 1295 } |
1296 | 1296 |
1297 if (doWorkaround) { | 1297 if (doWorkaround) { |
1298 // Clean up. | 1298 // Clean up. |
1299 GLC(m_context, m_context->bindFramebuffer(GL_FRAMEBUFFER, 0)); | 1299 GLC(m_context, m_context->bindFramebuffer(GL_FRAMEBUFFER, 0)); |
1300 GLC(m_context, m_context->bindTexture(GL_TEXTURE_2D, 0)); | 1300 GLC(m_context, m_context->bindTexture(GL_TEXTURE_2D, 0)); |
1301 GLC(m_context, m_context->deleteFramebuffer(temporaryFBO)); | 1301 GLC(m_context, m_context->deleteFramebuffer(temporaryFBO)); |
1302 GLC(m_context, m_context->deleteTexture(temporaryTexture)); | 1302 GLC(m_context, m_context->deleteTexture(temporaryTexture)); |
1303 } | 1303 } |
1304 | 1304 |
1305 enforceMemoryPolicy(); | 1305 enforceMemoryPolicy(); |
1306 } | 1306 } |
1307 | 1307 |
1308 bool GLRenderer::getFramebufferTexture(ScopedTexture* texture, const IntRect& de
viceRect) | 1308 bool GLRenderer::getFramebufferTexture(ScopedTexture* texture, const gfx::Rect&
deviceRect) |
1309 { | 1309 { |
1310 DCHECK(!texture->id() || (texture->size() == deviceRect.size() && texture->f
ormat() == GL_RGB)); | 1310 DCHECK(!texture->id() || (texture->size() == deviceRect.size() && texture->f
ormat() == GL_RGB)); |
1311 | 1311 |
1312 if (!texture->id() && !texture->allocate(Renderer::ImplPool, cc::IntSize(dev
iceRect.size()), GL_RGB, ResourceProvider::TextureUsageAny)) | 1312 if (!texture->id() && !texture->allocate(Renderer::ImplPool, deviceRect.size
(), GL_RGB, ResourceProvider::TextureUsageAny)) |
1313 return false; | 1313 return false; |
1314 | 1314 |
1315 ResourceProvider::ScopedWriteLockGL lock(m_resourceProvider, texture->id()); | 1315 ResourceProvider::ScopedWriteLockGL lock(m_resourceProvider, texture->id()); |
1316 GLC(m_context, m_context->bindTexture(GL_TEXTURE_2D, lock.textureId())); | 1316 GLC(m_context, m_context->bindTexture(GL_TEXTURE_2D, lock.textureId())); |
1317 GLC(m_context, m_context->copyTexImage2D(GL_TEXTURE_2D, 0, texture->format()
, | 1317 GLC(m_context, m_context->copyTexImage2D(GL_TEXTURE_2D, 0, texture->format()
, |
1318 deviceRect.x(), deviceRect.y(), dev
iceRect.width(), deviceRect.height(), 0)); | 1318 deviceRect.x(), deviceRect.y(), dev
iceRect.width(), deviceRect.height(), 0)); |
1319 return true; | 1319 return true; |
1320 } | 1320 } |
1321 | 1321 |
1322 bool GLRenderer::useScopedTexture(DrawingFrame& frame, const ScopedTexture* text
ure, const gfx::Rect& viewportRect) | 1322 bool GLRenderer::useScopedTexture(DrawingFrame& frame, const ScopedTexture* text
ure, const gfx::Rect& viewportRect) |
(...skipping 303 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1626 | 1626 |
1627 releaseRenderPassTextures(); | 1627 releaseRenderPassTextures(); |
1628 } | 1628 } |
1629 | 1629 |
1630 bool GLRenderer::isContextLost() | 1630 bool GLRenderer::isContextLost() |
1631 { | 1631 { |
1632 return (m_context->getGraphicsResetStatusARB() != GL_NO_ERROR); | 1632 return (m_context->getGraphicsResetStatusARB() != GL_NO_ERROR); |
1633 } | 1633 } |
1634 | 1634 |
1635 } // namespace cc | 1635 } // namespace cc |
OLD | NEW |