Changeset 92037 in webkit
- Timestamp:
- Jul 29, 2011 6:26:02 PM (13 years ago)
- Location:
- trunk/Source/WebCore
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/WebCore/ChangeLog
r92035 r92037 1 2011-07-29 James Robinson <jamesr@chromium.org> 2 3 [chromium] Reorder functions in LayerRendererChromium.cpp to make bug 58840 easier to review 4 https://bugs.webkit.org/show_bug.cgi?id=65354 5 6 Reviewed by Kenneth Russell. 7 8 This moves a few function definitions in LayerRendererChromium around to make the patch on bug 58840 easier to 9 review. In that patch, updatePropertiesAndRenderSurfaces() becomes a templated free function instead of a 10 member function, so it has to be near the top of the .cpp. 11 12 * platform/graphics/chromium/LayerRendererChromium.cpp: 13 (WebCore::calculateVisibleRect): 14 (WebCore::isScaleOrTranslation): 15 (WebCore::LayerRendererChromium::updatePropertiesAndRenderSurfaces): 16 (WebCore::LayerRendererChromium::updateLayers): 17 1 18 2011-07-29 Jeff Miller <jeffm@apple.com> 2 19 -
trunk/Source/WebCore/platform/graphics/chromium/LayerRendererChromium.cpp
r91821 r92037 78 78 #endif 79 79 80 static TransformationMatrix orthoMatrix(float left, float right, float bottom, float top)81 {82 float deltaX = right - left;83 float deltaY = top - bottom;84 TransformationMatrix ortho;85 if (!deltaX || !deltaY)86 return ortho;87 ortho.setM11(2.0f / deltaX);88 ortho.setM41(-(right + left) / deltaX);89 ortho.setM22(2.0f / deltaY);90 ortho.setM42(-(top + bottom) / deltaY);91 92 // Z component of vertices is always set to zero as we don't use the depth buffer93 // while drawing.94 ortho.setM33(0);95 96 return ortho;97 }98 99 // Returns true if the matrix has no rotation, skew or perspective components to it.100 static bool isScaleOrTranslation(const TransformationMatrix& m)101 {102 return !m.m12() && !m.m13() && !m.m14()103 && !m.m21() && !m.m23() && !m.m24()104 && !m.m31() && !m.m32() && !m.m43()105 && m.m44();106 107 }108 109 PassRefPtr<LayerRendererChromium> LayerRendererChromium::create(CCLayerTreeHostClient* client, PassOwnPtr<LayerPainterChromium> contentPaint, bool accelerateDrawing)110 {111 RefPtr<GraphicsContext3D> context = client->createLayerTreeHostContext3D();112 if (!context)113 return 0;114 115 RefPtr<LayerRendererChromium> layerRenderer(adoptRef(new LayerRendererChromium(client, context, contentPaint, accelerateDrawing)));116 layerRenderer->init();117 if (!layerRenderer->hardwareCompositing())118 return 0;119 120 return layerRenderer.release();121 }122 123 LayerRendererChromium::LayerRendererChromium(CCLayerTreeHostClient* client,124 PassRefPtr<GraphicsContext3D> context,125 PassOwnPtr<LayerPainterChromium> contentPaint,126 bool accelerateDrawing)127 : CCLayerTreeHost(client)128 , m_viewportScrollPosition(IntPoint(-1, -1))129 , m_rootLayer(0)130 , m_accelerateDrawing(false)131 , m_currentRenderSurface(0)132 , m_offscreenFramebufferId(0)133 , m_compositeOffscreen(false)134 , m_context(context)135 , m_contextSupportsTextureFormatBGRA(false)136 , m_contextSupportsReadFormatBGRA(false)137 , m_animating(false)138 , m_defaultRenderSurface(0)139 {140 WebCore::Extensions3D* extensions = m_context->getExtensions();141 m_contextSupportsMapSub = extensions->supports("GL_CHROMIUM_map_sub");142 if (m_contextSupportsMapSub)143 extensions->ensureEnabled("GL_CHROMIUM_map_sub");144 m_contextSupportsTextureFormatBGRA = extensions->supports("GL_EXT_texture_format_BGRA8888");145 if (m_contextSupportsTextureFormatBGRA)146 extensions->ensureEnabled("GL_EXT_texture_format_BGRA8888");147 m_contextSupportsReadFormatBGRA = extensions->supports("GL_EXT_read_format_bgra");148 if (m_contextSupportsReadFormatBGRA)149 extensions->ensureEnabled("GL_EXT_read_format_bgra");150 151 #if USE(SKIA)152 m_accelerateDrawing = accelerateDrawing && skiaContext();153 #endif154 m_hardwareCompositing = initializeSharedObjects();155 156 #if USE(SKIA)157 if (m_accelerateDrawing)158 m_rootLayerTextureUpdater = LayerTextureUpdaterSkPicture::create(m_context.get(), contentPaint, skiaContext());159 else160 #endif161 m_rootLayerTextureUpdater = LayerTextureUpdaterBitmap::create(m_context.get(), contentPaint, m_contextSupportsMapSub);162 163 m_rootLayerContentTiler = LayerTilerChromium::create(this, IntSize(256, 256), LayerTilerChromium::NoBorderTexels);164 ASSERT(m_rootLayerContentTiler);165 166 m_headsUpDisplay = CCHeadsUpDisplay::create(this);167 }168 169 LayerRendererChromium::~LayerRendererChromium()170 {171 m_headsUpDisplay.clear(); // Explicitly destroy the HUD before the TextureManager dies.172 cleanupSharedObjects();173 }174 175 GraphicsContext3D* LayerRendererChromium::context()176 {177 return m_context.get();178 }179 180 #if USE(SKIA)181 GrContext* LayerRendererChromium::skiaContext()182 {183 if (!m_skiaContext && m_contextSupportsTextureFormatBGRA && m_contextSupportsReadFormatBGRA) {184 m_context->makeContextCurrent();185 m_skiaContext = adoptPtr(GrContext::CreateGLShaderContext());186 // Limit the number of textures we hold in the bitmap->texture cache.187 static const int maxTextureCacheCount = 512;188 // Limit the bytes allocated toward textures in the bitmap->texture cache.189 static const size_t maxTextureCacheBytes = 50 * 1024 * 1024;190 m_skiaContext->setTextureCacheLimits(maxTextureCacheCount, maxTextureCacheBytes);191 }192 return m_skiaContext.get();193 }194 #endif195 196 void LayerRendererChromium::debugGLCall(GraphicsContext3D* context, const char* command, const char* file, int line)197 {198 unsigned long error = context->getError();199 if (error != GraphicsContext3D::NO_ERROR)200 LOG_ERROR("GL command failed: File: %s\n\tLine %d\n\tcommand: %s, error %x\n", file, line, command, static_cast<int>(error));201 }202 203 void LayerRendererChromium::invalidateRootLayerRect(const IntRect& dirtyRect)204 {205 m_rootLayerContentTiler->invalidateRect(dirtyRect);206 }207 208 void LayerRendererChromium::releaseTextures()209 {210 // Reduces texture memory usage to textureMemoryLowLimitBytes by deleting non root layer211 // textures.212 m_rootLayerContentTiler->protectTileTextures(m_viewportVisibleRect);213 m_contentsTextureManager->reduceMemoryToLimit(textureMemoryLowLimitBytes);214 m_contentsTextureManager->unprotectAllTextures();215 // Evict all RenderSurface textures.216 m_renderSurfaceTextureManager->unprotectAllTextures();217 m_renderSurfaceTextureManager->reduceMemoryToLimit(0);218 }219 220 void LayerRendererChromium::updateRootLayerContents()221 {222 TRACE_EVENT("LayerRendererChromium::updateRootLayerContents", this, 0);223 m_rootLayerContentTiler->prepareToUpdate(m_viewportVisibleRect, m_rootLayerTextureUpdater.get());224 }225 226 void LayerRendererChromium::drawRootLayer()227 {228 TransformationMatrix scroll;229 scroll.translate(-m_viewportVisibleRect.x(), -m_viewportVisibleRect.y());230 231 m_rootLayerContentTiler->draw(m_viewportVisibleRect, scroll, 1.0f);232 }233 234 void LayerRendererChromium::setViewport(const IntRect& visibleRect, const IntRect& contentRect, const IntPoint& scrollPosition)235 {236 bool visibleRectChanged = m_viewportVisibleRect.size() != visibleRect.size();237 238 m_viewportVisibleRect = visibleRect;239 m_viewportContentRect = contentRect;240 m_viewportScrollPosition = scrollPosition;241 242 if (visibleRectChanged) {243 // Reset the current render surface to force an update of the viewport and244 // projection matrix next time useRenderSurface is called.245 m_currentRenderSurface = 0;246 m_rootLayerContentTiler->invalidateEntireLayer();247 }248 setNeedsCommitAndRedraw();249 }250 251 void LayerRendererChromium::updateLayers()252 {253 if (m_viewportVisibleRect.isEmpty())254 return;255 256 // FIXME: use the frame begin time from the overall compositor scheduler.257 // This value is currently inaccessible because it is up in Chromium's258 // RenderWidget.259 m_headsUpDisplay->onFrameBegin(currentTime());260 ASSERT(m_hardwareCompositing);261 262 if (!m_rootLayer)263 return;264 265 updateRootLayerContents();266 267 // Recheck that we still have a root layer. This may become null if268 // compositing gets turned off during a paint operation.269 if (!m_rootLayer)270 return;271 272 {273 TRACE_EVENT("LayerRendererChromium::synchronizeTrees", this, 0);274 m_rootCCLayerImpl = TreeSynchronizer::synchronizeTrees(m_rootLayer.get(), m_rootCCLayerImpl.get());275 }276 277 m_computedRenderSurfaceLayerList = adoptPtr(new LayerList());278 updateLayers(*m_computedRenderSurfaceLayerList);279 }280 281 void LayerRendererChromium::drawLayers()282 {283 ASSERT(m_hardwareCompositing);284 ASSERT(m_computedRenderSurfaceLayerList);285 // Before drawLayers:286 if (hardwareCompositing()) {287 // FIXME: The multithreaded compositor case will not work as long as288 // copyTexImage2D resolves to the parent texture, because the main289 // thread can execute WebGL calls on the child context at any time,290 // potentially clobbering the parent texture that is being renderered291 // by the compositor thread.292 ChildContextMap::iterator i = m_childContexts.begin();293 for (; i != m_childContexts.end(); ++i) {294 i->first->flush();295 }296 }297 298 m_renderSurfaceTextureManager->setMemoryLimitBytes(textureMemoryHighLimitBytes - m_contentsTextureManager->currentMemoryUseBytes());299 drawLayers(*m_computedRenderSurfaceLayerList);300 301 m_contentsTextureManager->unprotectAllTextures();302 m_contentsTextureManager->reduceMemoryToLimit(textureMemoryReclaimLimitBytes);303 304 if (textureMemoryReclaimLimitBytes > m_contentsTextureManager->currentMemoryUseBytes())305 m_renderSurfaceTextureManager->reduceMemoryToLimit(textureMemoryReclaimLimitBytes - m_contentsTextureManager->currentMemoryUseBytes());306 else307 m_renderSurfaceTextureManager->reduceMemoryToLimit(0);308 309 if (isCompositingOffscreen())310 copyOffscreenTextureToDisplay();311 }312 313 void LayerRendererChromium::updateLayers(LayerList& renderSurfaceLayerList)314 {315 TRACE_EVENT("LayerRendererChromium::updateLayers", this, 0);316 CCLayerImpl* rootDrawLayer = m_rootLayer->ccLayerImpl();317 318 if (!rootDrawLayer->renderSurface())319 rootDrawLayer->createRenderSurface();320 ASSERT(rootDrawLayer->renderSurface());321 322 rootDrawLayer->renderSurface()->setContentRect(IntRect(IntPoint(0, 0), m_viewportVisibleRect.size()));323 324 IntRect rootScissorRect(m_viewportVisibleRect);325 // The scissorRect should not include the scroll offset.326 rootScissorRect.move(-m_viewportScrollPosition.x(), -m_viewportScrollPosition.y());327 rootDrawLayer->setScissorRect(rootScissorRect);328 329 m_defaultRenderSurface = rootDrawLayer->renderSurface();330 331 renderSurfaceLayerList.append(rootDrawLayer);332 333 TransformationMatrix identityMatrix;334 m_defaultRenderSurface->clearLayerList();335 // Unfortunately, updatePropertiesAndRenderSurfaces() currently both updates the layers and updates the draw state336 // (transforms, etc). It'd be nicer if operations on the presentation layers happened later, but the draw337 // transforms are needed by large layers to determine visibility. Tiling will fix this by eliminating the338 // concept of a large content layer.339 updatePropertiesAndRenderSurfaces(rootDrawLayer, identityMatrix, renderSurfaceLayerList, m_defaultRenderSurface->layerList());340 341 #ifndef NDEBUG342 s_inPaintLayerContents = true;343 #endif344 paintLayerContents(renderSurfaceLayerList);345 #ifndef NDEBUG346 s_inPaintLayerContents = false;347 #endif348 // Update compositor resources for root layer.349 {350 TRACE_EVENT("LayerRendererChromium::updateLayer::updateRoot", this, 0);351 m_rootLayerContentTiler->updateRect(m_rootLayerTextureUpdater.get());352 }353 354 m_contentsTextureManager->reduceMemoryToLimit(textureMemoryReclaimLimitBytes);355 updateCompositorResources(renderSurfaceLayerList);356 }357 358 80 static IntRect calculateVisibleRect(const IntRect& targetSurfaceRect, const IntRect& layerBoundRect, const TransformationMatrix& transform) 359 81 { … … 379 101 } 380 102 381 static IntRect calculateVisibleLayerRect(const IntRect& targetSurfaceRect, const IntSize& bounds, const IntSize& contentBounds, const TransformationMatrix& tilingTransform) 382 { 383 if (targetSurfaceRect.isEmpty() || contentBounds.isEmpty()) 384 return targetSurfaceRect; 385 386 const IntRect layerBoundRect = IntRect(IntPoint(), contentBounds); 387 TransformationMatrix transform = tilingTransform; 388 389 transform.scaleNonUniform(bounds.width() / static_cast<double>(contentBounds.width()), 390 bounds.height() / static_cast<double>(contentBounds.height())); 391 transform.translate(-contentBounds.width() / 2.0, -contentBounds.height() / 2.0); 392 393 return calculateVisibleRect(targetSurfaceRect, layerBoundRect, transform); 394 } 395 396 static void paintContentsIfDirty(LayerChromium* layer, const IntRect& visibleLayerRect) 397 { 398 if (layer->drawsContent()) { 399 layer->setVisibleLayerRect(visibleLayerRect); 400 layer->paintContentsIfDirty(); 401 } 402 } 403 404 void LayerRendererChromium::paintLayerContents(const LayerList& renderSurfaceLayerList) 405 { 406 for (int surfaceIndex = renderSurfaceLayerList.size() - 1; surfaceIndex >= 0 ; --surfaceIndex) { 407 CCLayerImpl* renderSurfaceLayer = renderSurfaceLayerList[surfaceIndex].get(); 408 RenderSurfaceChromium* renderSurface = renderSurfaceLayer->renderSurface(); 409 ASSERT(renderSurface); 410 411 // Make sure any renderSurfaceLayer is associated with this layerRenderer. 412 // This is a defensive assignment in case the owner of this layer hasn't 413 // set the layerRenderer on this layer already. 414 renderSurfaceLayer->setLayerRenderer(this); 415 416 // Render surfaces whose drawable area has zero width or height 417 // will have no layers associated with them and should be skipped. 418 if (!renderSurface->layerList().size()) 419 continue; 420 421 if (!renderSurface->drawOpacity()) 422 continue; 423 424 LayerList& layerList = renderSurface->layerList(); 425 ASSERT(layerList.size()); 426 for (unsigned layerIndex = 0; layerIndex < layerList.size(); ++layerIndex) { 427 CCLayerImpl* ccLayerImpl = layerList[layerIndex].get(); 428 429 // Layers that start a new render surface will be painted when the render 430 // surface's list is processed. 431 if (ccLayerImpl->renderSurface() && ccLayerImpl->renderSurface() != renderSurface) 432 continue; 433 434 LayerChromium* layer = ccLayerImpl->owner(); 435 436 layer->setLayerRenderer(this); 437 438 if (!layer->opacity()) 439 continue; 440 441 if (layer->maskLayer()) 442 layer->maskLayer()->setLayerRenderer(this); 443 if (layer->replicaLayer()) { 444 layer->replicaLayer()->setLayerRenderer(this); 445 if (layer->replicaLayer()->maskLayer()) 446 layer->replicaLayer()->maskLayer()->setLayerRenderer(this); 447 } 448 449 if (layer->bounds().isEmpty()) 450 continue; 451 452 IntRect targetSurfaceRect = ccLayerImpl->targetRenderSurface() ? ccLayerImpl->targetRenderSurface()->contentRect() : m_defaultRenderSurface->contentRect(); 453 if (layer->ccLayerImpl()->usesLayerScissor()) 454 targetSurfaceRect.intersect(layer->ccLayerImpl()->scissorRect()); 455 IntRect visibleLayerRect = calculateVisibleLayerRect(targetSurfaceRect, layer->bounds(), layer->contentBounds(), ccLayerImpl->drawTransform()); 456 457 paintContentsIfDirty(layer, visibleLayerRect); 458 459 if (LayerChromium* maskLayer = layer->maskLayer()) { 460 paintContentsIfDirty(maskLayer, IntRect(IntPoint(), maskLayer->contentBounds())); 461 } 462 463 if (LayerChromium* replicaLayer = layer->replicaLayer()) { 464 paintContentsIfDirty(replicaLayer, visibleLayerRect); 465 466 if (LayerChromium* replicaMaskLayer = replicaLayer->maskLayer()) { 467 paintContentsIfDirty(replicaMaskLayer, IntRect(IntPoint(), replicaMaskLayer->contentBounds())); 468 } 469 } 470 } 471 } 472 } 473 474 void LayerRendererChromium::drawLayers(const LayerList& renderSurfaceLayerList) 475 { 476 if (m_viewportVisibleRect.isEmpty() || !m_rootLayer) 477 return; 478 479 TRACE_EVENT("LayerRendererChromium::drawLayers", this, 0); 480 CCLayerImpl* rootDrawLayer = m_rootLayer->ccLayerImpl(); 481 makeContextCurrent(); 482 483 // The GL viewport covers the entire visible area, including the scrollbars. 484 GLC(m_context.get(), m_context->viewport(0, 0, m_viewportVisibleRect.width(), m_viewportVisibleRect.height())); 485 486 // Bind the common vertex attributes used for drawing all the layers. 487 m_sharedGeometry->prepareForDraw(); 488 489 // FIXME: These calls can be made once, when the compositor context is initialized. 490 GLC(m_context.get(), m_context->disable(GraphicsContext3D::DEPTH_TEST)); 491 GLC(m_context.get(), m_context->disable(GraphicsContext3D::CULL_FACE)); 492 493 // Blending disabled by default. Root layer alpha channel on Windows is incorrect when Skia uses ClearType. 494 GLC(m_context.get(), m_context->disable(GraphicsContext3D::BLEND)); 495 496 useRenderSurface(m_defaultRenderSurface); 497 498 // Clear to blue to make it easier to spot unrendered regions. 499 m_context->clearColor(0, 0, 1, 1); 500 m_context->colorMask(true, true, true, true); 501 m_context->clear(GraphicsContext3D::COLOR_BUFFER_BIT); 502 // Mask out writes to alpha channel: subpixel antialiasing via Skia results in invalid 503 // zero alpha values on text glyphs. The root layer is always opaque. 504 m_context->colorMask(true, true, true, false); 505 506 drawRootLayer(); 507 508 // Re-enable color writes to layers, which may be partially transparent. 509 m_context->colorMask(true, true, true, true); 510 511 GLC(m_context.get(), m_context->enable(GraphicsContext3D::BLEND)); 512 GLC(m_context.get(), m_context->blendFunc(GraphicsContext3D::ONE, GraphicsContext3D::ONE_MINUS_SRC_ALPHA)); 513 GLC(m_context.get(), m_context->enable(GraphicsContext3D::SCISSOR_TEST)); 514 515 // Update the contents of the render surfaces. We traverse the array from 516 // back to front to guarantee that nested render surfaces get rendered in the 517 // correct order. 518 for (int surfaceIndex = renderSurfaceLayerList.size() - 1; surfaceIndex >= 0 ; --surfaceIndex) { 519 CCLayerImpl* renderSurfaceLayer = renderSurfaceLayerList[surfaceIndex].get(); 520 RenderSurfaceChromium* renderSurface = renderSurfaceLayer->renderSurface(); 521 ASSERT(renderSurface); 522 523 renderSurface->setSkipsDraw(true); 524 525 // Render surfaces whose drawable area has zero width or height 526 // will have no layers associated with them and should be skipped. 527 if (!renderSurface->layerList().size()) 528 continue; 529 530 // Skip completely transparent render surfaces. 531 if (!renderSurface->drawOpacity()) 532 continue; 533 534 if (useRenderSurface(renderSurface)) { 535 renderSurface->setSkipsDraw(false); 536 537 if (renderSurfaceLayer != rootDrawLayer) { 538 GLC(m_context.get(), m_context->disable(GraphicsContext3D::SCISSOR_TEST)); 539 GLC(m_context.get(), m_context->clearColor(0, 0, 0, 0)); 540 GLC(m_context.get(), m_context->clear(GraphicsContext3D::COLOR_BUFFER_BIT)); 541 GLC(m_context.get(), m_context->enable(GraphicsContext3D::SCISSOR_TEST)); 542 } 543 544 LayerList& layerList = renderSurface->layerList(); 545 for (unsigned layerIndex = 0; layerIndex < layerList.size(); ++layerIndex) 546 drawLayer(layerList[layerIndex].get(), renderSurface); 547 } 548 } 549 550 if (m_headsUpDisplay->enabled()) { 551 GLC(m_context.get(), m_context->enable(GraphicsContext3D::BLEND)); 552 GLC(m_context.get(), m_context->blendFunc(GraphicsContext3D::ONE, GraphicsContext3D::ONE_MINUS_SRC_ALPHA)); 553 GLC(m_context.get(), m_context->disable(GraphicsContext3D::SCISSOR_TEST)); 554 useRenderSurface(m_defaultRenderSurface); 555 m_headsUpDisplay->draw(); 556 } 557 558 GLC(m_context.get(), m_context->disable(GraphicsContext3D::SCISSOR_TEST)); 559 GLC(m_context.get(), m_context->disable(GraphicsContext3D::BLEND)); 560 } 561 562 void LayerRendererChromium::finish() 563 { 564 TRACE_EVENT("LayerRendererChromium::finish", this, 0); 565 m_context->finish(); 566 } 567 568 void LayerRendererChromium::present() 569 { 570 TRACE_EVENT("LayerRendererChromium::present", this, 0); 571 // We're done! Time to swapbuffers! 572 573 // Note that currently this has the same effect as swapBuffers; we should 574 // consider exposing a different entry point on GraphicsContext3D. 575 m_context->prepareTexture(); 576 577 m_headsUpDisplay->onPresent(); 578 } 579 580 void LayerRendererChromium::setRootLayer(PassRefPtr<LayerChromium> layer) 581 { 582 m_rootLayer = layer; 583 if (m_rootLayer) 584 m_rootLayer->setLayerRenderer(this); 585 m_rootLayerContentTiler->invalidateEntireLayer(); 586 } 587 588 void LayerRendererChromium::setLayerRendererRecursive(LayerChromium* layer) 589 { 590 const Vector<RefPtr<LayerChromium> >& children = layer->children(); 591 for (size_t i = 0; i < children.size(); ++i) 592 setLayerRendererRecursive(children[i].get()); 593 594 if (layer->maskLayer()) 595 setLayerRendererRecursive(layer->maskLayer()); 596 if (layer->replicaLayer()) 597 setLayerRendererRecursive(layer->replicaLayer()); 598 599 layer->setLayerRenderer(this); 600 } 601 602 void LayerRendererChromium::transferRootLayer(LayerRendererChromium* other) 603 { 604 other->setLayerRendererRecursive(m_rootLayer.get()); 605 other->m_rootLayer = m_rootLayer.release(); 606 } 607 608 void LayerRendererChromium::getFramebufferPixels(void *pixels, const IntRect& rect) 609 { 610 ASSERT(rect.maxX() <= m_viewportVisibleRect.width() && rect.maxY() <= m_viewportVisibleRect.height()); 611 612 if (!pixels) 613 return; 614 615 makeContextCurrent(); 616 617 GLC(m_context.get(), m_context->readPixels(rect.x(), rect.y(), rect.width(), rect.height(), 618 GraphicsContext3D::RGBA, GraphicsContext3D::UNSIGNED_BYTE, pixels)); 619 } 620 621 // FIXME: This method should eventually be replaced by a proper texture manager. 622 unsigned LayerRendererChromium::createLayerTexture() 623 { 624 unsigned textureId = 0; 625 GLC(m_context.get(), textureId = m_context->createTexture()); 626 GLC(m_context.get(), m_context->bindTexture(GraphicsContext3D::TEXTURE_2D, textureId)); 627 // Do basic linear filtering on resize. 628 GLC(m_context.get(), m_context->texParameteri(GraphicsContext3D::TEXTURE_2D, GraphicsContext3D::TEXTURE_MIN_FILTER, GraphicsContext3D::LINEAR)); 629 GLC(m_context.get(), m_context->texParameteri(GraphicsContext3D::TEXTURE_2D, GraphicsContext3D::TEXTURE_MAG_FILTER, GraphicsContext3D::LINEAR)); 630 // NPOT textures in GL ES only work when the wrap mode is set to GraphicsContext3D::CLAMP_TO_EDGE. 631 GLC(m_context.get(), m_context->texParameteri(GraphicsContext3D::TEXTURE_2D, GraphicsContext3D::TEXTURE_WRAP_S, GraphicsContext3D::CLAMP_TO_EDGE)); 632 GLC(m_context.get(), m_context->texParameteri(GraphicsContext3D::TEXTURE_2D, GraphicsContext3D::TEXTURE_WRAP_T, GraphicsContext3D::CLAMP_TO_EDGE)); 633 return textureId; 634 } 635 636 void LayerRendererChromium::deleteLayerTexture(unsigned textureId) 637 { 638 if (!textureId) 639 return; 640 641 GLC(m_context.get(), m_context->deleteTexture(textureId)); 642 } 643 644 // Returns true if any part of the layer falls within the visibleRect 645 bool LayerRendererChromium::isLayerVisible(LayerChromium* layer, const TransformationMatrix& matrix, const IntRect& visibleRect) 646 { 647 // Form the matrix used by the shader to map the corners of the layer's 648 // bounds into clip space. 649 TransformationMatrix renderMatrix = matrix; 650 renderMatrix.scale3d(layer->bounds().width(), layer->bounds().height(), 1); 651 renderMatrix = m_projectionMatrix * renderMatrix; 652 653 FloatRect layerRect(-0.5, -0.5, 1, 1); 654 FloatRect mappedRect = renderMatrix.mapRect(layerRect); 655 656 // The layer is visible if it intersects any part of a rectangle whose origin 657 // is at (-1, -1) and size is 2x2. 658 return mappedRect.intersects(FloatRect(-1, -1, 2, 2)); 103 // Returns true if the matrix has no rotation, skew or perspective components to it. 104 static bool isScaleOrTranslation(const TransformationMatrix& m) 105 { 106 return !m.m12() && !m.m13() && !m.m14() 107 && !m.m21() && !m.m23() && !m.m24() 108 && !m.m31() && !m.m32() && !m.m43() 109 && m.m44(); 110 659 111 } 660 112 … … 906 358 } 907 359 908 // If preserves-3d then sort all the descendants in 3D so that they can be 360 // If preserves-3d then sort all the descendants in 3D so that they can be 909 361 // drawn from back to front. If the preserves-3d property is also set on the parent then 910 362 // skip the sorting as the parent will sort all the descendants anyway. 911 363 if (layer->preserves3D() && (!layer->parent() || !layer->parent()->preserves3D())) 912 364 m_layerSorter.sort(&descendants.at(thisLayerIndex), descendants.end()); 365 } 366 367 static TransformationMatrix orthoMatrix(float left, float right, float bottom, float top) 368 { 369 float deltaX = right - left; 370 float deltaY = top - bottom; 371 TransformationMatrix ortho; 372 if (!deltaX || !deltaY) 373 return ortho; 374 ortho.setM11(2.0f / deltaX); 375 ortho.setM41(-(right + left) / deltaX); 376 ortho.setM22(2.0f / deltaY); 377 ortho.setM42(-(top + bottom) / deltaY); 378 379 // Z component of vertices is always set to zero as we don't use the depth buffer 380 // while drawing. 381 ortho.setM33(0); 382 383 return ortho; 384 } 385 386 PassRefPtr<LayerRendererChromium> LayerRendererChromium::create(CCLayerTreeHostClient* client, PassOwnPtr<LayerPainterChromium> contentPaint, bool accelerateDrawing) 387 { 388 RefPtr<GraphicsContext3D> context = client->createLayerTreeHostContext3D(); 389 if (!context) 390 return 0; 391 392 RefPtr<LayerRendererChromium> layerRenderer(adoptRef(new LayerRendererChromium(client, context, contentPaint, accelerateDrawing))); 393 layerRenderer->init(); 394 if (!layerRenderer->hardwareCompositing()) 395 return 0; 396 397 return layerRenderer.release(); 398 } 399 400 LayerRendererChromium::LayerRendererChromium(CCLayerTreeHostClient* client, 401 PassRefPtr<GraphicsContext3D> context, 402 PassOwnPtr<LayerPainterChromium> contentPaint, 403 bool accelerateDrawing) 404 : CCLayerTreeHost(client) 405 , m_viewportScrollPosition(IntPoint(-1, -1)) 406 , m_rootLayer(0) 407 , m_accelerateDrawing(false) 408 , m_currentRenderSurface(0) 409 , m_offscreenFramebufferId(0) 410 , m_compositeOffscreen(false) 411 , m_context(context) 412 , m_contextSupportsTextureFormatBGRA(false) 413 , m_contextSupportsReadFormatBGRA(false) 414 , m_animating(false) 415 , m_defaultRenderSurface(0) 416 { 417 WebCore::Extensions3D* extensions = m_context->getExtensions(); 418 m_contextSupportsMapSub = extensions->supports("GL_CHROMIUM_map_sub"); 419 if (m_contextSupportsMapSub) 420 extensions->ensureEnabled("GL_CHROMIUM_map_sub"); 421 m_contextSupportsTextureFormatBGRA = extensions->supports("GL_EXT_texture_format_BGRA8888"); 422 if (m_contextSupportsTextureFormatBGRA) 423 extensions->ensureEnabled("GL_EXT_texture_format_BGRA8888"); 424 m_contextSupportsReadFormatBGRA = extensions->supports("GL_EXT_read_format_bgra"); 425 if (m_contextSupportsReadFormatBGRA) 426 extensions->ensureEnabled("GL_EXT_read_format_bgra"); 427 428 #if USE(SKIA) 429 m_accelerateDrawing = accelerateDrawing && skiaContext(); 430 #endif 431 m_hardwareCompositing = initializeSharedObjects(); 432 433 #if USE(SKIA) 434 if (m_accelerateDrawing) 435 m_rootLayerTextureUpdater = LayerTextureUpdaterSkPicture::create(m_context.get(), contentPaint, skiaContext()); 436 else 437 #endif 438 m_rootLayerTextureUpdater = LayerTextureUpdaterBitmap::create(m_context.get(), contentPaint, m_contextSupportsMapSub); 439 440 m_rootLayerContentTiler = LayerTilerChromium::create(this, IntSize(256, 256), LayerTilerChromium::NoBorderTexels); 441 ASSERT(m_rootLayerContentTiler); 442 443 m_headsUpDisplay = CCHeadsUpDisplay::create(this); 444 } 445 446 LayerRendererChromium::~LayerRendererChromium() 447 { 448 m_headsUpDisplay.clear(); // Explicitly destroy the HUD before the TextureManager dies. 449 cleanupSharedObjects(); 450 } 451 452 GraphicsContext3D* LayerRendererChromium::context() 453 { 454 return m_context.get(); 455 } 456 457 #if USE(SKIA) 458 GrContext* LayerRendererChromium::skiaContext() 459 { 460 if (!m_skiaContext && m_contextSupportsTextureFormatBGRA && m_contextSupportsReadFormatBGRA) { 461 m_context->makeContextCurrent(); 462 m_skiaContext = adoptPtr(GrContext::CreateGLShaderContext()); 463 // Limit the number of textures we hold in the bitmap->texture cache. 464 static const int maxTextureCacheCount = 512; 465 // Limit the bytes allocated toward textures in the bitmap->texture cache. 466 static const size_t maxTextureCacheBytes = 50 * 1024 * 1024; 467 m_skiaContext->setTextureCacheLimits(maxTextureCacheCount, maxTextureCacheBytes); 468 } 469 return m_skiaContext.get(); 470 } 471 #endif 472 473 void LayerRendererChromium::debugGLCall(GraphicsContext3D* context, const char* command, const char* file, int line) 474 { 475 unsigned long error = context->getError(); 476 if (error != GraphicsContext3D::NO_ERROR) 477 LOG_ERROR("GL command failed: File: %s\n\tLine %d\n\tcommand: %s, error %x\n", file, line, command, static_cast<int>(error)); 478 } 479 480 void LayerRendererChromium::invalidateRootLayerRect(const IntRect& dirtyRect) 481 { 482 m_rootLayerContentTiler->invalidateRect(dirtyRect); 483 } 484 485 void LayerRendererChromium::releaseTextures() 486 { 487 // Reduces texture memory usage to textureMemoryLowLimitBytes by deleting non root layer 488 // textures. 489 m_rootLayerContentTiler->protectTileTextures(m_viewportVisibleRect); 490 m_contentsTextureManager->reduceMemoryToLimit(textureMemoryLowLimitBytes); 491 m_contentsTextureManager->unprotectAllTextures(); 492 // Evict all RenderSurface textures. 493 m_renderSurfaceTextureManager->unprotectAllTextures(); 494 m_renderSurfaceTextureManager->reduceMemoryToLimit(0); 495 } 496 497 void LayerRendererChromium::updateRootLayerContents() 498 { 499 TRACE_EVENT("LayerRendererChromium::updateRootLayerContents", this, 0); 500 m_rootLayerContentTiler->prepareToUpdate(m_viewportVisibleRect, m_rootLayerTextureUpdater.get()); 501 } 502 503 void LayerRendererChromium::drawRootLayer() 504 { 505 TransformationMatrix scroll; 506 scroll.translate(-m_viewportVisibleRect.x(), -m_viewportVisibleRect.y()); 507 508 m_rootLayerContentTiler->draw(m_viewportVisibleRect, scroll, 1.0f); 509 } 510 511 void LayerRendererChromium::setViewport(const IntRect& visibleRect, const IntRect& contentRect, const IntPoint& scrollPosition) 512 { 513 bool visibleRectChanged = m_viewportVisibleRect.size() != visibleRect.size(); 514 515 m_viewportVisibleRect = visibleRect; 516 m_viewportContentRect = contentRect; 517 m_viewportScrollPosition = scrollPosition; 518 519 if (visibleRectChanged) { 520 // Reset the current render surface to force an update of the viewport and 521 // projection matrix next time useRenderSurface is called. 522 m_currentRenderSurface = 0; 523 m_rootLayerContentTiler->invalidateEntireLayer(); 524 } 525 setNeedsCommitAndRedraw(); 526 } 527 528 void LayerRendererChromium::updateLayers() 529 { 530 if (m_viewportVisibleRect.isEmpty()) 531 return; 532 533 // FIXME: use the frame begin time from the overall compositor scheduler. 534 // This value is currently inaccessible because it is up in Chromium's 535 // RenderWidget. 536 m_headsUpDisplay->onFrameBegin(currentTime()); 537 ASSERT(m_hardwareCompositing); 538 539 if (!m_rootLayer) 540 return; 541 542 updateRootLayerContents(); 543 544 // Recheck that we still have a root layer. This may become null if 545 // compositing gets turned off during a paint operation. 546 if (!m_rootLayer) 547 return; 548 549 { 550 TRACE_EVENT("LayerRendererChromium::synchronizeTrees", this, 0); 551 m_rootCCLayerImpl = TreeSynchronizer::synchronizeTrees(m_rootLayer.get(), m_rootCCLayerImpl.get()); 552 } 553 554 m_computedRenderSurfaceLayerList = adoptPtr(new LayerList()); 555 updateLayers(*m_computedRenderSurfaceLayerList); 556 } 557 558 void LayerRendererChromium::drawLayers() 559 { 560 ASSERT(m_hardwareCompositing); 561 ASSERT(m_computedRenderSurfaceLayerList); 562 // Before drawLayers: 563 if (hardwareCompositing()) { 564 // FIXME: The multithreaded compositor case will not work as long as 565 // copyTexImage2D resolves to the parent texture, because the main 566 // thread can execute WebGL calls on the child context at any time, 567 // potentially clobbering the parent texture that is being renderered 568 // by the compositor thread. 569 ChildContextMap::iterator i = m_childContexts.begin(); 570 for (; i != m_childContexts.end(); ++i) { 571 i->first->flush(); 572 } 573 } 574 575 m_renderSurfaceTextureManager->setMemoryLimitBytes(textureMemoryHighLimitBytes - m_contentsTextureManager->currentMemoryUseBytes()); 576 drawLayers(*m_computedRenderSurfaceLayerList); 577 578 m_contentsTextureManager->unprotectAllTextures(); 579 m_contentsTextureManager->reduceMemoryToLimit(textureMemoryReclaimLimitBytes); 580 581 if (textureMemoryReclaimLimitBytes > m_contentsTextureManager->currentMemoryUseBytes()) 582 m_renderSurfaceTextureManager->reduceMemoryToLimit(textureMemoryReclaimLimitBytes - m_contentsTextureManager->currentMemoryUseBytes()); 583 else 584 m_renderSurfaceTextureManager->reduceMemoryToLimit(0); 585 586 if (isCompositingOffscreen()) 587 copyOffscreenTextureToDisplay(); 588 } 589 590 void LayerRendererChromium::updateLayers(LayerList& renderSurfaceLayerList) 591 { 592 TRACE_EVENT("LayerRendererChromium::updateLayers", this, 0); 593 CCLayerImpl* rootDrawLayer = m_rootLayer->ccLayerImpl(); 594 595 if (!rootDrawLayer->renderSurface()) 596 rootDrawLayer->createRenderSurface(); 597 ASSERT(rootDrawLayer->renderSurface()); 598 599 rootDrawLayer->renderSurface()->setContentRect(IntRect(IntPoint(0, 0), m_viewportVisibleRect.size())); 600 601 IntRect rootScissorRect(m_viewportVisibleRect); 602 // The scissorRect should not include the scroll offset. 603 rootScissorRect.move(-m_viewportScrollPosition.x(), -m_viewportScrollPosition.y()); 604 rootDrawLayer->setScissorRect(rootScissorRect); 605 606 m_defaultRenderSurface = rootDrawLayer->renderSurface(); 607 608 renderSurfaceLayerList.append(rootDrawLayer); 609 610 TransformationMatrix identityMatrix; 611 m_defaultRenderSurface->clearLayerList(); 612 // Unfortunately, updatePropertiesAndRenderSurfaces() currently both updates the layers and updates the draw state 613 // (transforms, etc). It'd be nicer if operations on the presentation layers happened later, but the draw 614 // transforms are needed by large layers to determine visibility. Tiling will fix this by eliminating the 615 // concept of a large content layer. 616 updatePropertiesAndRenderSurfaces(rootDrawLayer, identityMatrix, renderSurfaceLayerList, m_defaultRenderSurface->layerList()); 617 618 #ifndef NDEBUG 619 s_inPaintLayerContents = true; 620 #endif 621 paintLayerContents(renderSurfaceLayerList); 622 #ifndef NDEBUG 623 s_inPaintLayerContents = false; 624 #endif 625 // Update compositor resources for root layer. 626 { 627 TRACE_EVENT("LayerRendererChromium::updateLayer::updateRoot", this, 0); 628 m_rootLayerContentTiler->updateRect(m_rootLayerTextureUpdater.get()); 629 } 630 631 m_contentsTextureManager->reduceMemoryToLimit(textureMemoryReclaimLimitBytes); 632 updateCompositorResources(renderSurfaceLayerList); 633 } 634 635 static IntRect calculateVisibleLayerRect(const IntRect& targetSurfaceRect, const IntSize& bounds, const IntSize& contentBounds, const TransformationMatrix& tilingTransform) 636 { 637 if (targetSurfaceRect.isEmpty() || contentBounds.isEmpty()) 638 return targetSurfaceRect; 639 640 const IntRect layerBoundRect = IntRect(IntPoint(), contentBounds); 641 TransformationMatrix transform = tilingTransform; 642 643 transform.scaleNonUniform(bounds.width() / static_cast<double>(contentBounds.width()), 644 bounds.height() / static_cast<double>(contentBounds.height())); 645 transform.translate(-contentBounds.width() / 2.0, -contentBounds.height() / 2.0); 646 647 return calculateVisibleRect(targetSurfaceRect, layerBoundRect, transform); 648 } 649 650 static void paintContentsIfDirty(LayerChromium* layer, const IntRect& visibleLayerRect) 651 { 652 if (layer->drawsContent()) { 653 layer->setVisibleLayerRect(visibleLayerRect); 654 layer->paintContentsIfDirty(); 655 } 656 } 657 658 void LayerRendererChromium::paintLayerContents(const LayerList& renderSurfaceLayerList) 659 { 660 for (int surfaceIndex = renderSurfaceLayerList.size() - 1; surfaceIndex >= 0 ; --surfaceIndex) { 661 CCLayerImpl* renderSurfaceLayer = renderSurfaceLayerList[surfaceIndex].get(); 662 RenderSurfaceChromium* renderSurface = renderSurfaceLayer->renderSurface(); 663 ASSERT(renderSurface); 664 665 // Make sure any renderSurfaceLayer is associated with this layerRenderer. 666 // This is a defensive assignment in case the owner of this layer hasn't 667 // set the layerRenderer on this layer already. 668 renderSurfaceLayer->setLayerRenderer(this); 669 670 // Render surfaces whose drawable area has zero width or height 671 // will have no layers associated with them and should be skipped. 672 if (!renderSurface->layerList().size()) 673 continue; 674 675 if (!renderSurface->drawOpacity()) 676 continue; 677 678 LayerList& layerList = renderSurface->layerList(); 679 ASSERT(layerList.size()); 680 for (unsigned layerIndex = 0; layerIndex < layerList.size(); ++layerIndex) { 681 CCLayerImpl* ccLayerImpl = layerList[layerIndex].get(); 682 683 // Layers that start a new render surface will be painted when the render 684 // surface's list is processed. 685 if (ccLayerImpl->renderSurface() && ccLayerImpl->renderSurface() != renderSurface) 686 continue; 687 688 LayerChromium* layer = ccLayerImpl->owner(); 689 690 layer->setLayerRenderer(this); 691 692 if (!layer->opacity()) 693 continue; 694 695 if (layer->maskLayer()) 696 layer->maskLayer()->setLayerRenderer(this); 697 if (layer->replicaLayer()) { 698 layer->replicaLayer()->setLayerRenderer(this); 699 if (layer->replicaLayer()->maskLayer()) 700 layer->replicaLayer()->maskLayer()->setLayerRenderer(this); 701 } 702 703 if (layer->bounds().isEmpty()) 704 continue; 705 706 IntRect targetSurfaceRect = ccLayerImpl->targetRenderSurface() ? ccLayerImpl->targetRenderSurface()->contentRect() : m_defaultRenderSurface->contentRect(); 707 if (layer->ccLayerImpl()->usesLayerScissor()) 708 targetSurfaceRect.intersect(layer->ccLayerImpl()->scissorRect()); 709 IntRect visibleLayerRect = calculateVisibleLayerRect(targetSurfaceRect, layer->bounds(), layer->contentBounds(), ccLayerImpl->drawTransform()); 710 711 paintContentsIfDirty(layer, visibleLayerRect); 712 713 if (LayerChromium* maskLayer = layer->maskLayer()) { 714 paintContentsIfDirty(maskLayer, IntRect(IntPoint(), maskLayer->contentBounds())); 715 } 716 717 if (LayerChromium* replicaLayer = layer->replicaLayer()) { 718 paintContentsIfDirty(replicaLayer, visibleLayerRect); 719 720 if (LayerChromium* replicaMaskLayer = replicaLayer->maskLayer()) { 721 paintContentsIfDirty(replicaMaskLayer, IntRect(IntPoint(), replicaMaskLayer->contentBounds())); 722 } 723 } 724 } 725 } 726 } 727 728 void LayerRendererChromium::drawLayers(const LayerList& renderSurfaceLayerList) 729 { 730 if (m_viewportVisibleRect.isEmpty() || !m_rootLayer) 731 return; 732 733 TRACE_EVENT("LayerRendererChromium::drawLayers", this, 0); 734 CCLayerImpl* rootDrawLayer = m_rootLayer->ccLayerImpl(); 735 makeContextCurrent(); 736 737 // The GL viewport covers the entire visible area, including the scrollbars. 738 GLC(m_context.get(), m_context->viewport(0, 0, m_viewportVisibleRect.width(), m_viewportVisibleRect.height())); 739 740 // Bind the common vertex attributes used for drawing all the layers. 741 m_sharedGeometry->prepareForDraw(); 742 743 // FIXME: These calls can be made once, when the compositor context is initialized. 744 GLC(m_context.get(), m_context->disable(GraphicsContext3D::DEPTH_TEST)); 745 GLC(m_context.get(), m_context->disable(GraphicsContext3D::CULL_FACE)); 746 747 // Blending disabled by default. Root layer alpha channel on Windows is incorrect when Skia uses ClearType. 748 GLC(m_context.get(), m_context->disable(GraphicsContext3D::BLEND)); 749 750 useRenderSurface(m_defaultRenderSurface); 751 752 // Clear to blue to make it easier to spot unrendered regions. 753 m_context->clearColor(0, 0, 1, 1); 754 m_context->colorMask(true, true, true, true); 755 m_context->clear(GraphicsContext3D::COLOR_BUFFER_BIT); 756 // Mask out writes to alpha channel: subpixel antialiasing via Skia results in invalid 757 // zero alpha values on text glyphs. The root layer is always opaque. 758 m_context->colorMask(true, true, true, false); 759 760 drawRootLayer(); 761 762 // Re-enable color writes to layers, which may be partially transparent. 763 m_context->colorMask(true, true, true, true); 764 765 GLC(m_context.get(), m_context->enable(GraphicsContext3D::BLEND)); 766 GLC(m_context.get(), m_context->blendFunc(GraphicsContext3D::ONE, GraphicsContext3D::ONE_MINUS_SRC_ALPHA)); 767 GLC(m_context.get(), m_context->enable(GraphicsContext3D::SCISSOR_TEST)); 768 769 // Update the contents of the render surfaces. We traverse the array from 770 // back to front to guarantee that nested render surfaces get rendered in the 771 // correct order. 772 for (int surfaceIndex = renderSurfaceLayerList.size() - 1; surfaceIndex >= 0 ; --surfaceIndex) { 773 CCLayerImpl* renderSurfaceLayer = renderSurfaceLayerList[surfaceIndex].get(); 774 RenderSurfaceChromium* renderSurface = renderSurfaceLayer->renderSurface(); 775 ASSERT(renderSurface); 776 777 renderSurface->setSkipsDraw(true); 778 779 // Render surfaces whose drawable area has zero width or height 780 // will have no layers associated with them and should be skipped. 781 if (!renderSurface->layerList().size()) 782 continue; 783 784 // Skip completely transparent render surfaces. 785 if (!renderSurface->drawOpacity()) 786 continue; 787 788 if (useRenderSurface(renderSurface)) { 789 renderSurface->setSkipsDraw(false); 790 791 if (renderSurfaceLayer != rootDrawLayer) { 792 GLC(m_context.get(), m_context->disable(GraphicsContext3D::SCISSOR_TEST)); 793 GLC(m_context.get(), m_context->clearColor(0, 0, 0, 0)); 794 GLC(m_context.get(), m_context->clear(GraphicsContext3D::COLOR_BUFFER_BIT)); 795 GLC(m_context.get(), m_context->enable(GraphicsContext3D::SCISSOR_TEST)); 796 } 797 798 LayerList& layerList = renderSurface->layerList(); 799 for (unsigned layerIndex = 0; layerIndex < layerList.size(); ++layerIndex) 800 drawLayer(layerList[layerIndex].get(), renderSurface); 801 } 802 } 803 804 if (m_headsUpDisplay->enabled()) { 805 GLC(m_context.get(), m_context->enable(GraphicsContext3D::BLEND)); 806 GLC(m_context.get(), m_context->blendFunc(GraphicsContext3D::ONE, GraphicsContext3D::ONE_MINUS_SRC_ALPHA)); 807 GLC(m_context.get(), m_context->disable(GraphicsContext3D::SCISSOR_TEST)); 808 useRenderSurface(m_defaultRenderSurface); 809 m_headsUpDisplay->draw(); 810 } 811 812 GLC(m_context.get(), m_context->disable(GraphicsContext3D::SCISSOR_TEST)); 813 GLC(m_context.get(), m_context->disable(GraphicsContext3D::BLEND)); 814 } 815 816 void LayerRendererChromium::finish() 817 { 818 TRACE_EVENT("LayerRendererChromium::finish", this, 0); 819 m_context->finish(); 820 } 821 822 void LayerRendererChromium::present() 823 { 824 TRACE_EVENT("LayerRendererChromium::present", this, 0); 825 // We're done! Time to swapbuffers! 826 827 // Note that currently this has the same effect as swapBuffers; we should 828 // consider exposing a different entry point on GraphicsContext3D. 829 m_context->prepareTexture(); 830 831 m_headsUpDisplay->onPresent(); 832 } 833 834 void LayerRendererChromium::setRootLayer(PassRefPtr<LayerChromium> layer) 835 { 836 m_rootLayer = layer; 837 if (m_rootLayer) 838 m_rootLayer->setLayerRenderer(this); 839 m_rootLayerContentTiler->invalidateEntireLayer(); 840 } 841 842 void LayerRendererChromium::setLayerRendererRecursive(LayerChromium* layer) 843 { 844 const Vector<RefPtr<LayerChromium> >& children = layer->children(); 845 for (size_t i = 0; i < children.size(); ++i) 846 setLayerRendererRecursive(children[i].get()); 847 848 if (layer->maskLayer()) 849 setLayerRendererRecursive(layer->maskLayer()); 850 if (layer->replicaLayer()) 851 setLayerRendererRecursive(layer->replicaLayer()); 852 853 layer->setLayerRenderer(this); 854 } 855 856 void LayerRendererChromium::transferRootLayer(LayerRendererChromium* other) 857 { 858 other->setLayerRendererRecursive(m_rootLayer.get()); 859 other->m_rootLayer = m_rootLayer.release(); 860 } 861 862 void LayerRendererChromium::getFramebufferPixels(void *pixels, const IntRect& rect) 863 { 864 ASSERT(rect.maxX() <= m_viewportVisibleRect.width() && rect.maxY() <= m_viewportVisibleRect.height()); 865 866 if (!pixels) 867 return; 868 869 makeContextCurrent(); 870 871 GLC(m_context.get(), m_context->readPixels(rect.x(), rect.y(), rect.width(), rect.height(), 872 GraphicsContext3D::RGBA, GraphicsContext3D::UNSIGNED_BYTE, pixels)); 873 } 874 875 // FIXME: This method should eventually be replaced by a proper texture manager. 876 unsigned LayerRendererChromium::createLayerTexture() 877 { 878 unsigned textureId = 0; 879 GLC(m_context.get(), textureId = m_context->createTexture()); 880 GLC(m_context.get(), m_context->bindTexture(GraphicsContext3D::TEXTURE_2D, textureId)); 881 // Do basic linear filtering on resize. 882 GLC(m_context.get(), m_context->texParameteri(GraphicsContext3D::TEXTURE_2D, GraphicsContext3D::TEXTURE_MIN_FILTER, GraphicsContext3D::LINEAR)); 883 GLC(m_context.get(), m_context->texParameteri(GraphicsContext3D::TEXTURE_2D, GraphicsContext3D::TEXTURE_MAG_FILTER, GraphicsContext3D::LINEAR)); 884 // NPOT textures in GL ES only work when the wrap mode is set to GraphicsContext3D::CLAMP_TO_EDGE. 885 GLC(m_context.get(), m_context->texParameteri(GraphicsContext3D::TEXTURE_2D, GraphicsContext3D::TEXTURE_WRAP_S, GraphicsContext3D::CLAMP_TO_EDGE)); 886 GLC(m_context.get(), m_context->texParameteri(GraphicsContext3D::TEXTURE_2D, GraphicsContext3D::TEXTURE_WRAP_T, GraphicsContext3D::CLAMP_TO_EDGE)); 887 return textureId; 888 } 889 890 void LayerRendererChromium::deleteLayerTexture(unsigned textureId) 891 { 892 if (!textureId) 893 return; 894 895 GLC(m_context.get(), m_context->deleteTexture(textureId)); 896 } 897 898 // Returns true if any part of the layer falls within the visibleRect 899 bool LayerRendererChromium::isLayerVisible(LayerChromium* layer, const TransformationMatrix& matrix, const IntRect& visibleRect) 900 { 901 // Form the matrix used by the shader to map the corners of the layer's 902 // bounds into clip space. 903 TransformationMatrix renderMatrix = matrix; 904 renderMatrix.scale3d(layer->bounds().width(), layer->bounds().height(), 1); 905 renderMatrix = m_projectionMatrix * renderMatrix; 906 907 FloatRect layerRect(-0.5, -0.5, 1, 1); 908 FloatRect mappedRect = renderMatrix.mapRect(layerRect); 909 910 // The layer is visible if it intersects any part of a rectangle whose origin 911 // is at (-1, -1) and size is 2x2. 912 return mappedRect.intersects(FloatRect(-1, -1, 2, 2)); 913 913 } 914 914
Note: See TracChangeset
for help on using the changeset viewer.