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 438 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
449 // FIXME: Do a single readback for both the surface and replica and cache th
e filtered results (once filter textures are not reused). | 449 // FIXME: Do a single readback for both the surface and replica and cache th
e filtered results (once filter textures are not reused). |
450 gfx::Rect deviceRect = gfx::ToEnclosingRect(MathUtil::mapClippedRect(content
sDeviceTransform, cc::FloatRect(sharedGeometryQuad().boundingBox()))); | 450 gfx::Rect deviceRect = gfx::ToEnclosingRect(MathUtil::mapClippedRect(content
sDeviceTransform, cc::FloatRect(sharedGeometryQuad().boundingBox()))); |
451 | 451 |
452 int top, right, bottom, left; | 452 int top, right, bottom, left; |
453 filters.getOutsets(top, right, bottom, left); | 453 filters.getOutsets(top, right, bottom, left); |
454 deviceRect.Inset(-left, -top, -right, -bottom); | 454 deviceRect.Inset(-left, -top, -right, -bottom); |
455 | 455 |
456 deviceRect.Intersect(frame.currentRenderPass->outputRect()); | 456 deviceRect.Intersect(frame.currentRenderPass->outputRect()); |
457 | 457 |
458 scoped_ptr<ScopedTexture> deviceBackgroundTexture = ScopedTexture::create(m_
resourceProvider); | 458 scoped_ptr<ScopedTexture> deviceBackgroundTexture = ScopedTexture::create(m_
resourceProvider); |
459 if (!getFramebufferTexture(deviceBackgroundTexture.get(), cc::IntRect(device
Rect))) | 459 if (!getFramebufferTexture(deviceBackgroundTexture.get(), deviceRect)) |
460 return scoped_ptr<ScopedTexture>(); | 460 return scoped_ptr<ScopedTexture>(); |
461 | 461 |
462 SkBitmap filteredDeviceBackground = applyFilters(this, filters, deviceBackgr
oundTexture.get()); | 462 SkBitmap filteredDeviceBackground = applyFilters(this, filters, deviceBackgr
oundTexture.get()); |
463 if (!filteredDeviceBackground.getTexture()) | 463 if (!filteredDeviceBackground.getTexture()) |
464 return scoped_ptr<ScopedTexture>(); | 464 return scoped_ptr<ScopedTexture>(); |
465 | 465 |
466 GrTexture* texture = reinterpret_cast<GrTexture*>(filteredDeviceBackground.g
etTexture()); | 466 GrTexture* texture = reinterpret_cast<GrTexture*>(filteredDeviceBackground.g
etTexture()); |
467 int filteredDeviceBackgroundTextureId = texture->getTextureHandle(); | 467 int filteredDeviceBackgroundTextureId = texture->getTextureHandle(); |
468 | 468 |
469 scoped_ptr<ScopedTexture> backgroundTexture = ScopedTexture::create(m_resour
ceProvider); | 469 scoped_ptr<ScopedTexture> backgroundTexture = ScopedTexture::create(m_resour
ceProvider); |
(...skipping 213 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
683 // minus epsilon for one pixel layers. The resulting clamp region | 683 // minus epsilon for one pixel layers. The resulting clamp region |
684 // is mapped to the unit square by the vertex shader and mapped | 684 // is mapped to the unit square by the vertex shader and mapped |
685 // back to normalized texture coordinates by the fragment shader | 685 // back to normalized texture coordinates by the fragment shader |
686 // after being clamped to 0-1 range. | 686 // after being clamped to 0-1 range. |
687 const float epsilon = 1 / 1024.0f; | 687 const float epsilon = 1 / 1024.0f; |
688 float clampX = min(0.5, clampRect.width() / 2.0 - epsilon); | 688 float clampX = min(0.5, clampRect.width() / 2.0 - epsilon); |
689 float clampY = min(0.5, clampRect.height() / 2.0 - epsilon); | 689 float clampY = min(0.5, clampRect.height() / 2.0 - epsilon); |
690 clampRect.Inset(clampX, clampY, clampX, clampY); | 690 clampRect.Inset(clampX, clampY, clampX, clampY); |
691 gfx::Vector2dF clampOffset = clampRect.origin() - tileRect.origin(); | 691 gfx::Vector2dF clampOffset = clampRect.origin() - tileRect.origin(); |
692 | 692 |
693 gfx::PointF textureOffset = quad->textureOffset() + clampOffset + | 693 gfx::Vector2dF textureOffset = quad->textureOffset() + clampOffset + |
694 (tileRect.origin() - quad->quadRect().origin()); | 694 (tileRect.origin() - quad->quadRect().origin(
)); |
695 | 695 |
696 // Map clamping rectangle to unit square. | 696 // Map clamping rectangle to unit square. |
697 float vertexTexTranslateX = -clampRect.x() / clampRect.width(); | 697 float vertexTexTranslateX = -clampRect.x() / clampRect.width(); |
698 float vertexTexTranslateY = -clampRect.y() / clampRect.height(); | 698 float vertexTexTranslateY = -clampRect.y() / clampRect.height(); |
699 float vertexTexScaleX = tileRect.width() / clampRect.width(); | 699 float vertexTexScaleX = tileRect.width() / clampRect.width(); |
700 float vertexTexScaleY = tileRect.height() / clampRect.height(); | 700 float vertexTexScaleY = tileRect.height() / clampRect.height(); |
701 | 701 |
702 // Map to normalized texture coordinates. | 702 // Map to normalized texture coordinates. |
703 const gfx::Size& textureSize = quad->textureSize(); | 703 const gfx::Size& textureSize = quad->textureSize(); |
704 float fragmentTexTranslateX = textureOffset.x() / textureSize.width(); | 704 float fragmentTexTranslateX = textureOffset.x() / textureSize.width(); |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
755 deviceLayerEdges.inflateAntiAliasingDistance(); | 755 deviceLayerEdges.inflateAntiAliasingDistance(); |
756 | 756 |
757 float edge[24]; | 757 float edge[24]; |
758 deviceLayerEdges.toFloatArray(edge); | 758 deviceLayerEdges.toFloatArray(edge); |
759 deviceLayerBounds.toFloatArray(&edge[12]); | 759 deviceLayerBounds.toFloatArray(&edge[12]); |
760 GLC(context(), context()->uniform3fv(uniforms.edgeLocation, 8, edge)); | 760 GLC(context(), context()->uniform3fv(uniforms.edgeLocation, 8, edge)); |
761 | 761 |
762 GLC(context(), context()->uniform4f(uniforms.vertexTexTransformLocation,
vertexTexTranslateX, vertexTexTranslateY, vertexTexScaleX, vertexTexScaleY)); | 762 GLC(context(), context()->uniform4f(uniforms.vertexTexTransformLocation,
vertexTexTranslateX, vertexTexTranslateY, vertexTexScaleX, vertexTexScaleY)); |
763 GLC(context(), context()->uniform4f(uniforms.fragmentTexTransformLocatio
n, fragmentTexTranslateX, fragmentTexTranslateY, fragmentTexScaleX, fragmentTexS
caleY)); | 763 GLC(context(), context()->uniform4f(uniforms.fragmentTexTransformLocatio
n, fragmentTexTranslateX, fragmentTexTranslateY, fragmentTexScaleX, fragmentTexS
caleY)); |
764 | 764 |
765 FloatPoint bottomRight(tileRect.right(), tileRect.bottom()); | 765 gfx::PointF bottomRight(tileRect.right(), tileRect.bottom()); |
766 FloatPoint bottomLeft(tileRect.x(), tileRect.bottom()); | 766 gfx::PointF bottomLeft(tileRect.x(), tileRect.bottom()); |
767 FloatPoint topLeft(tileRect.x(), tileRect.y()); | 767 gfx::PointF topLeft(tileRect.x(), tileRect.y()); |
768 FloatPoint topRight(tileRect.right(), tileRect.y()); | 768 gfx::PointF topRight(tileRect.right(), tileRect.y()); |
769 | 769 |
770 // Map points to device space. | 770 // Map points to device space. |
771 bottomRight = MathUtil::mapPoint(deviceTransform, bottomRight, clipped); | 771 bottomRight = MathUtil::mapPoint(deviceTransform, bottomRight, clipped); |
772 DCHECK(!clipped); | 772 DCHECK(!clipped); |
773 bottomLeft = MathUtil::mapPoint(deviceTransform, bottomLeft, clipped); | 773 bottomLeft = MathUtil::mapPoint(deviceTransform, bottomLeft, clipped); |
774 DCHECK(!clipped); | 774 DCHECK(!clipped); |
775 topLeft = MathUtil::mapPoint(deviceTransform, topLeft, clipped); | 775 topLeft = MathUtil::mapPoint(deviceTransform, topLeft, clipped); |
776 DCHECK(!clipped); | 776 DCHECK(!clipped); |
777 topRight = MathUtil::mapPoint(deviceTransform, topRight, clipped); | 777 topRight = MathUtil::mapPoint(deviceTransform, topRight, clipped); |
778 DCHECK(!clipped); | 778 DCHECK(!clipped); |
(...skipping 413 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1192 m_context->ensureFramebufferCHROMIUM(); | 1192 m_context->ensureFramebufferCHROMIUM(); |
1193 m_isFramebufferDiscarded = false; | 1193 m_isFramebufferDiscarded = false; |
1194 } | 1194 } |
1195 | 1195 |
1196 void GLRenderer::onContextLost() | 1196 void GLRenderer::onContextLost() |
1197 { | 1197 { |
1198 m_client->didLoseContext(); | 1198 m_client->didLoseContext(); |
1199 } | 1199 } |
1200 | 1200 |
1201 | 1201 |
1202 void GLRenderer::getFramebufferPixels(void *pixels, const IntRect& rect) | 1202 void GLRenderer::getFramebufferPixels(void *pixels, const gfx::Rect& rect) |
1203 { | 1203 { |
1204 DCHECK(rect.maxX() <= viewportWidth()); | 1204 DCHECK(rect.right() <= viewportWidth()); |
1205 DCHECK(rect.maxY() <= viewportHeight()); | 1205 DCHECK(rect.bottom() <= viewportHeight()); |
1206 | 1206 |
1207 if (!pixels) | 1207 if (!pixels) |
1208 return; | 1208 return; |
1209 | 1209 |
1210 makeContextCurrent(); | 1210 makeContextCurrent(); |
1211 | 1211 |
1212 bool doWorkaround = needsIOSurfaceReadbackWorkaround(); | 1212 bool doWorkaround = needsIOSurfaceReadbackWorkaround(); |
1213 | 1213 |
1214 GLuint temporaryTexture = 0; | 1214 GLuint temporaryTexture = 0; |
1215 GLuint temporaryFBO = 0; | 1215 GLuint temporaryFBO = 0; |
(...skipping 14 matching lines...) Expand all Loading... |
1230 GLC(m_context, m_context->copyTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 0, 0
, viewportSize().width(), viewportSize().height(), 0)); | 1230 GLC(m_context, m_context->copyTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 0, 0
, viewportSize().width(), viewportSize().height(), 0)); |
1231 temporaryFBO = m_context->createFramebuffer(); | 1231 temporaryFBO = m_context->createFramebuffer(); |
1232 // Attach this texture to an FBO, and perform the readback from that FBO
. | 1232 // Attach this texture to an FBO, and perform the readback from that FBO
. |
1233 GLC(m_context, m_context->bindFramebuffer(GL_FRAMEBUFFER, temporaryFBO))
; | 1233 GLC(m_context, m_context->bindFramebuffer(GL_FRAMEBUFFER, temporaryFBO))
; |
1234 GLC(m_context, m_context->framebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_
ATTACHMENT0, GL_TEXTURE_2D, temporaryTexture, 0)); | 1234 GLC(m_context, m_context->framebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_
ATTACHMENT0, GL_TEXTURE_2D, temporaryTexture, 0)); |
1235 | 1235 |
1236 DCHECK(m_context->checkFramebufferStatus(GL_FRAMEBUFFER) == GL_FRAMEBUFF
ER_COMPLETE); | 1236 DCHECK(m_context->checkFramebufferStatus(GL_FRAMEBUFFER) == GL_FRAMEBUFF
ER_COMPLETE); |
1237 } | 1237 } |
1238 | 1238 |
1239 scoped_array<uint8_t> srcPixels(new uint8_t[rect.width() * rect.height() * 4
]); | 1239 scoped_array<uint8_t> srcPixels(new uint8_t[rect.width() * rect.height() * 4
]); |
1240 GLC(m_context, m_context->readPixels(rect.x(), viewportSize().height() - rec
t.maxY(), rect.width(), rect.height(), | 1240 GLC(m_context, m_context->readPixels(rect.x(), viewportSize().height() - rec
t.bottom(), rect.width(), rect.height(), |
1241 GL_RGBA, GL_UNSIGNED_BYTE, srcPixels.get())
); | 1241 GL_RGBA, GL_UNSIGNED_BYTE, srcPixels.ge
t())); |
1242 | 1242 |
1243 uint8_t* destPixels = static_cast<uint8_t*>(pixels); | 1243 uint8_t* destPixels = static_cast<uint8_t*>(pixels); |
1244 size_t rowBytes = rect.width() * 4; | 1244 size_t rowBytes = rect.width() * 4; |
1245 int numRows = rect.height(); | 1245 int numRows = rect.height(); |
1246 size_t totalBytes = numRows * rowBytes; | 1246 size_t totalBytes = numRows * rowBytes; |
1247 for (size_t destY = 0; destY < totalBytes; destY += rowBytes) { | 1247 for (size_t destY = 0; destY < totalBytes; destY += rowBytes) { |
1248 // Flip Y axis. | 1248 // Flip Y axis. |
1249 size_t srcY = totalBytes - destY - rowBytes; | 1249 size_t srcY = totalBytes - destY - rowBytes; |
1250 // Swizzle BGRA -> RGBA. | 1250 // Swizzle BGRA -> RGBA. |
1251 for (size_t x = 0; x < rowBytes; x += 4) { | 1251 for (size_t x = 0; x < rowBytes; x += 4) { |
1252 destPixels[destY + (x+0)] = srcPixels.get()[srcY + (x+2)]; | 1252 destPixels[destY + (x+0)] = srcPixels.get()[srcY + (x+2)]; |
1253 destPixels[destY + (x+1)] = srcPixels.get()[srcY + (x+1)]; | 1253 destPixels[destY + (x+1)] = srcPixels.get()[srcY + (x+1)]; |
1254 destPixels[destY + (x+2)] = srcPixels.get()[srcY + (x+0)]; | 1254 destPixels[destY + (x+2)] = srcPixels.get()[srcY + (x+0)]; |
1255 destPixels[destY + (x+3)] = srcPixels.get()[srcY + (x+3)]; | 1255 destPixels[destY + (x+3)] = srcPixels.get()[srcY + (x+3)]; |
1256 } | 1256 } |
1257 } | 1257 } |
1258 | 1258 |
1259 if (doWorkaround) { | 1259 if (doWorkaround) { |
1260 // Clean up. | 1260 // Clean up. |
1261 GLC(m_context, m_context->bindFramebuffer(GL_FRAMEBUFFER, 0)); | 1261 GLC(m_context, m_context->bindFramebuffer(GL_FRAMEBUFFER, 0)); |
1262 GLC(m_context, m_context->bindTexture(GL_TEXTURE_2D, 0)); | 1262 GLC(m_context, m_context->bindTexture(GL_TEXTURE_2D, 0)); |
1263 GLC(m_context, m_context->deleteFramebuffer(temporaryFBO)); | 1263 GLC(m_context, m_context->deleteFramebuffer(temporaryFBO)); |
1264 GLC(m_context, m_context->deleteTexture(temporaryTexture)); | 1264 GLC(m_context, m_context->deleteTexture(temporaryTexture)); |
1265 } | 1265 } |
1266 | 1266 |
1267 enforceMemoryPolicy(); | 1267 enforceMemoryPolicy(); |
1268 } | 1268 } |
1269 | 1269 |
1270 bool GLRenderer::getFramebufferTexture(ScopedTexture* texture, const IntRect& de
viceRect) | 1270 bool GLRenderer::getFramebufferTexture(ScopedTexture* texture, const gfx::Rect&
deviceRect) |
1271 { | 1271 { |
1272 DCHECK(!texture->id() || (texture->size() == deviceRect.size() && texture->f
ormat() == GL_RGB)); | 1272 DCHECK(!texture->id() || (texture->size() == deviceRect.size() && texture->f
ormat() == GL_RGB)); |
1273 | 1273 |
1274 if (!texture->id() && !texture->allocate(Renderer::ImplPool, cc::IntSize(dev
iceRect.size()), GL_RGB, ResourceProvider::TextureUsageAny)) | 1274 if (!texture->id() && !texture->allocate(Renderer::ImplPool, deviceRect.size
(), GL_RGB, ResourceProvider::TextureUsageAny)) |
1275 return false; | 1275 return false; |
1276 | 1276 |
1277 ResourceProvider::ScopedWriteLockGL lock(m_resourceProvider, texture->id()); | 1277 ResourceProvider::ScopedWriteLockGL lock(m_resourceProvider, texture->id()); |
1278 GLC(m_context, m_context->bindTexture(GL_TEXTURE_2D, lock.textureId())); | 1278 GLC(m_context, m_context->bindTexture(GL_TEXTURE_2D, lock.textureId())); |
1279 GLC(m_context, m_context->copyTexImage2D(GL_TEXTURE_2D, 0, texture->format()
, | 1279 GLC(m_context, m_context->copyTexImage2D(GL_TEXTURE_2D, 0, texture->format()
, |
1280 deviceRect.x(), deviceRect.y(), dev
iceRect.width(), deviceRect.height(), 0)); | 1280 deviceRect.x(), deviceRect.y(), dev
iceRect.width(), deviceRect.height(), 0)); |
1281 return true; | 1281 return true; |
1282 } | 1282 } |
1283 | 1283 |
1284 bool GLRenderer::useScopedTexture(DrawingFrame& frame, const ScopedTexture* text
ure, const gfx::Rect& viewportRect) | 1284 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... |
1588 | 1588 |
1589 releaseRenderPassTextures(); | 1589 releaseRenderPassTextures(); |
1590 } | 1590 } |
1591 | 1591 |
1592 bool GLRenderer::isContextLost() | 1592 bool GLRenderer::isContextLost() |
1593 { | 1593 { |
1594 return (m_context->getGraphicsResetStatusARB() != GL_NO_ERROR); | 1594 return (m_context->getGraphicsResetStatusARB() != GL_NO_ERROR); |
1595 } | 1595 } |
1596 | 1596 |
1597 } // namespace cc | 1597 } // namespace cc |
OLD | NEW |