Changeset 118696 in webkit
- Timestamp:
- May 28, 2012 10:29:10 AM (12 years ago)
- Location:
- trunk/Source
- Files:
-
- 12 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/WebCore/ChangeLog
r118688 r118696 1 2012-05-28 Arvid Nilsson <anilsson@rim.com> 2 3 [BlackBerry] Update WebPageCompositor::render() API 4 https://bugs.webkit.org/show_bug.cgi?id=87565 5 6 Reviewed by Rob Buis. 7 8 The new API allows the embedder to specify the root transform and many 9 OpenGL related parameters. 10 11 Also refactor the code to allow several sets of layers to be rendered, 12 and to allow interleaving the rendering of layers with rendering of 13 buffers and checkerboard. 14 15 Reviewed internally by Filip Spacek. 16 17 PR #154334 18 19 * platform/graphics/blackberry/LayerCompositingThread.cpp: 20 (WebCore::LayerCompositingThread::drawTextures): 21 (WebCore::LayerCompositingThread::drawSurface): 22 * platform/graphics/blackberry/LayerRenderer.cpp: 23 (WebCore::LayerRenderer::orthoMatrix): 24 (WebCore::LayerRenderer::LayerRenderer): 25 (WebCore::LayerRenderer::prepareFrame): 26 (WebCore): 27 (WebCore::LayerRenderer::setViewport): 28 (WebCore::LayerRenderer::compositeLayers): 29 (WebCore::LayerRenderer::compositeBuffer): 30 (WebCore::LayerRenderer::drawCheckerboardPattern): 31 (WebCore::LayerRenderer::drawLayersOnSurfaces): 32 (WebCore::LayerRenderer::prepareFrameRecursive): 33 (WebCore::LayerRenderer::updateLayersRecursive): 34 (WebCore::LayerRenderer::compositeLayersRecursive): 35 (WebCore::LayerRenderer::updateScissorIfNeeded): 36 (WebCore::LayerRenderingResults::addHolePunchRect): 37 * platform/graphics/blackberry/LayerRenderer.h: 38 (LayerRenderer): 39 1 40 2012-05-28 Antti Koivisto <antti@apple.com> 2 41 -
trunk/Source/WebCore/platform/graphics/blackberry/LayerCompositingThread.cpp
r118365 r118696 188 188 void LayerCompositingThread::drawTextures(int positionLocation, int texCoordLocation, const FloatRect& visibleRect) 189 189 { 190 float texcoords[4 * 2] = { 0, 0, 0, 1, 1, 1, 1, 0 };190 static float texcoords[4 * 2] = { 0, 0, 0, 1, 1, 1, 1, 0 }; 191 191 192 192 if (m_pluginView) { … … 280 280 glVertexAttribPointer(positionLocation, 2, GL_FLOAT, GL_FALSE, 0, &surfaceQuad); 281 281 282 float texcoords[4 * 2] = { 0, 0, 0, 1, 1, 1, 1, 0 };282 static float texcoords[4 * 2] = { 0, 0, 0, 1, 1, 1, 1, 0 }; 283 283 glVertexAttribPointer(texCoordLocation, 2, GL_FLOAT, GL_FALSE, 0, texcoords); 284 284 glDrawArrays(GL_TRIANGLE_FAN, 0, 4); -
trunk/Source/WebCore/platform/graphics/blackberry/LayerRenderer.cpp
r115506 r118696 41 41 #include "TextureCacheCompositingThread.h" 42 42 43 #include <BlackBerryPlatformGraphics.h> 43 44 #include <BlackBerryPlatformLog.h> 44 #include < wtf/CurrentTime.h>45 #include <limits> 45 46 #include <wtf/text/CString.h> 46 47 … … 50 51 #define DEBUG_DIRTY_LAYERS 0 // Show dirty layers as red. 51 52 #define DEBUG_LAYER_ANIMATIONS 0 // Show running animations as green. 52 #define DEBUG_ VIDEO_CLIPPING 053 #define DEBUG_CLIPPING 0 53 54 54 55 using BlackBerry::Platform::Graphics::GLES2Context; … … 117 118 } 118 119 119 static TransformationMatrixorthoMatrix(float left, float right, float bottom, float top, float nearZ, float farZ)120 TransformationMatrix LayerRenderer::orthoMatrix(float left, float right, float bottom, float top, float nearZ, float farZ) 120 121 { 121 122 float deltaX = right - left; … … 153 154 , m_positionLocation(0) 154 155 , m_texCoordLocation(1) 156 , m_animationTime(-numeric_limits<double>::infinity()) 155 157 , m_fbo(0) 156 158 , m_currentLayerRendererSurface(0) … … 208 210 } 209 211 210 // Re-composites all sublayers. 211 void LayerRenderer::drawLayers(const FloatRect& visibleRect, const IntRect& layoutRect, const IntSize& contentsSize, const IntRect& dstRect) 212 { 213 ASSERT(m_hardwareCompositing); 214 if (!m_hardwareCompositing) 212 void LayerRenderer::prepareFrame(double animationTime, LayerCompositingThread* rootLayer) 213 { 214 if (animationTime != m_animationTime) { 215 m_animationTime = animationTime; 216 217 // Aha, new frame! Reset rendering results. 218 bool wasEmpty = m_lastRenderingResults.isEmpty(); 219 m_lastRenderingResults = LayerRenderingResults(); 220 m_lastRenderingResults.wasEmpty = wasEmpty; 221 } 222 223 if (!rootLayer) 215 224 return; 216 225 217 bool wasEmpty = m_lastRenderingResults.isEmpty(); 218 m_lastRenderingResults = LayerRenderingResults(); 219 m_lastRenderingResults.wasEmpty = wasEmpty; 220 221 if (!m_rootLayer) 222 return; 223 226 bool isContextCurrent = makeContextCurrent(); 227 prepareFrameRecursive(rootLayer, animationTime, isContextCurrent); 228 } 229 230 void LayerRenderer::setViewport(const IntRect& targetRect, const IntRect& clipRect, const FloatRect& visibleRect, const IntRect& layoutRect, const IntSize& contentsSize) 231 { 224 232 // These parameters are used to calculate position of fixed position elements 225 233 m_visibleRect = visibleRect; … … 227 235 m_contentsSize = contentsSize; 228 236 229 // WebKit uses row vectors which are multiplied by the matrix on the left (i.e. v*M) 230 // Transformations are composed on the left so that M1.xform(M2) means M2*M1 231 // We therefore start with our (othogonal) projection matrix, which will be applied 232 // as the last transformation. 233 TransformationMatrix matrix = orthoMatrix(0, visibleRect.width(), visibleRect.height(), 0, -1000, 1000); 234 matrix.translate3d(-visibleRect.x(), -visibleRect.y(), 0); 235 236 // OpenGL window coordinates origin is at the lower left corner of the surface while 237 // WebKit uses upper left as the origin of the window coordinate system. The passed in 'dstRect' 238 // is in WebKit window coordinate system. Here we setup the viewport to the corresponding value 239 // in OpenGL window coordinates. 240 int viewportY = std::max(0, m_context->surfaceSize().height() - dstRect.maxY()); 241 m_viewport = IntRect(dstRect.x(), viewportY, dstRect.width(), dstRect.height()); 242 243 double animationTime = currentTime(); 244 245 #if DEBUG_VIDEO_CLIPPING 246 // Invoking updateLayersRecursive() which will call LayerCompositingThread::setDrawTransform(). 247 BlackBerry::Platform::log(BlackBerry::Platform::LogLevelInfo, "LayerRenderer::drawLayers() visible=(x=%.2f,y=%.2f,width=%.2f,height=%.2f), layout=(x=%d,y=%d,width=%d,height=%d), contents=(%dx%d), dst=(x=%d,y=%d,width=%d,height=%d).", 248 visibleRect.x(), visibleRect.y(), visibleRect.width(), visibleRect.height(), 249 layoutRect.x(), layoutRect.y(), layoutRect.width(), layoutRect.height(), 250 contentsSize.width(), contentsSize.height(), 251 dstRect.x(), dstRect.y(), dstRect.width(), dstRect.height()); 252 #endif 253 254 Vector<RefPtr<LayerCompositingThread> > surfaceLayers; 255 const Vector<RefPtr<LayerCompositingThread> >& sublayers = m_rootLayer->getSublayers(); 256 for (size_t i = 0; i < sublayers.size(); i++) { 257 float opacity = 1; 258 FloatRect clipRect(-1, -1, 2, 2); 259 updateLayersRecursive(sublayers[i].get(), matrix, surfaceLayers, opacity, clipRect, animationTime); 260 } 261 262 // Decompose the dirty rect into a set of non-overlaping rectangles 263 // (they need to not overlap so that the blending code doesn't draw any region twice). 264 for (int i = 0; i < LayerRenderingResults::NumberOfDirtyRects; ++i) { 265 BlackBerry::Platform::IntRectRegion region(BlackBerry::Platform::IntRect(m_lastRenderingResults.dirtyRect(i))); 266 m_lastRenderingResults.dirtyRegion = BlackBerry::Platform::IntRectRegion::unionRegions(m_lastRenderingResults.dirtyRegion, region); 267 } 268 269 // If we won't draw anything, don't touch the OpenGL APIs. 270 if (m_lastRenderingResults.isEmpty() && wasEmpty) 237 m_viewport = targetRect; 238 m_scissorRect = clipRect; 239 240 // The clipRect parameter uses render target coordinates, map to normalized device coordinates 241 m_clipRect = clipRect; 242 m_clipRect.intersect(targetRect); 243 m_clipRect = FloatRect(-1 + 2 * (m_clipRect.x() - targetRect.x()) / targetRect.width(), 244 -1 + 2 * (m_clipRect.y() - targetRect.y()) / targetRect.height(), 245 2 * m_clipRect.width() / targetRect.width(), 246 2 * m_clipRect.height() / targetRect.height()); 247 248 #if DEBUG_CLIPPING 249 printf("LayerRenderer::setViewport() m_visibleRect=(%.2f,%.2f %.2fx%.2f), m_layoutRect=(%d,%d %dx%d), m_contentsSize=(%dx%d), m_viewport=(%d,%d %dx%d), m_scissorRect=(%d,%d %dx%d), m_clipRect=(%.2f,%.2f %.2fx%.2f)\n", 250 m_visibleRect.x(), m_visibleRect.y(), m_visibleRect.width(), m_visibleRect.height(), 251 m_layoutRect.x(), m_layoutRect.y(), m_layoutRect.width(), m_layoutRect.height(), 252 m_contentsSize.width(), m_contentsSize.height(), 253 m_viewport.x(), m_viewport.y(), m_viewport.width(), m_viewport.height(), 254 m_scissorRect.x(), m_scissorRect.y(), m_scissorRect.width(), m_scissorRect.height(), 255 m_clipRect.x(), m_clipRect.y(), m_clipRect.width(), m_clipRect.height()); 256 fflush(stdout); 257 #endif 258 259 if (!m_hardwareCompositing) 271 260 return; 272 261 … … 294 283 glFrontFace(GL_CCW); 295 284 285 // Update the parameters for the checkerboard drawing. 286 glUseProgram(m_checkerProgramObject); 287 float bitmapScale = static_cast<float>(m_layoutRect.width()) / static_cast<float>(m_visibleRect.width()); 288 glUniform1f(m_checkerScaleLocation, bitmapScale); 289 float scale = static_cast<float>(m_viewport.width()) / static_cast<float>(m_visibleRect.width()); 290 glUniform2f(m_checkerOriginLocation, m_visibleRect.x()*scale, m_visibleRect.y()*scale); 291 glUniform1f(m_checkerSurfaceHeightLocation, m_context->surfaceSize().height()); 292 293 checkGLError(); 294 295 glViewport(m_viewport.x(), m_viewport.y(), m_viewport.width(), m_viewport.height()); 296 297 #if ENABLE_SCISSOR 298 glEnable(GL_SCISSOR_TEST); 299 #if DEBUG_CLIPPING 300 printf("LayerRenderer::compositeLayers(): clipping to (%d,%d %dx%d)\n", m_scissorRect.x(), m_scissorRect.y(), m_scissorRect.width(), m_scissorRect.height()); 301 fflush(stdout); 302 #endif 303 glScissor(m_scissorRect.x(), m_scissorRect.y(), m_scissorRect.width(), m_scissorRect.height()); 304 #endif 305 306 glClearStencil(0); 307 glClearColor(0, 0, 0, 0); 308 GLenum buffersToClear = GL_STENCIL_BUFFER_BIT; 309 if (m_clearSurfaceOnDrawLayers) 310 buffersToClear |= GL_COLOR_BUFFER_BIT; 311 glClear(buffersToClear); 312 } 313 314 void LayerRenderer::compositeLayers(const TransformationMatrix& matrix, LayerCompositingThread* rootLayer) 315 { 316 ASSERT(m_hardwareCompositing); 317 if (!m_hardwareCompositing) 318 return; 319 320 if (!rootLayer) 321 return; 322 323 Vector<RefPtr<LayerCompositingThread> > surfaceLayers; 324 const Vector<RefPtr<LayerCompositingThread> >& sublayers = rootLayer->getSublayers(); 325 for (size_t i = 0; i < sublayers.size(); i++) { 326 float opacity = 1; 327 FloatRect clipRect(m_clipRect); 328 updateLayersRecursive(sublayers[i].get(), matrix, surfaceLayers, opacity, clipRect); 329 } 330 331 // Decompose the dirty rect into a set of non-overlaping rectangles 332 // (they need to not overlap so that the blending code doesn't draw any region twice). 333 for (int i = 0; i < LayerRenderingResults::NumberOfDirtyRects; ++i) { 334 BlackBerry::Platform::IntRectRegion region(BlackBerry::Platform::IntRect(m_lastRenderingResults.dirtyRect(i))); 335 m_lastRenderingResults.dirtyRegion = BlackBerry::Platform::IntRectRegion::unionRegions(m_lastRenderingResults.dirtyRegion, region); 336 } 337 338 // If we won't draw anything, don't touch the OpenGL APIs. 339 if (m_lastRenderingResults.isEmpty() && m_lastRenderingResults.wasEmpty) 340 return; 341 342 // Okay, we're going to do some drawing. 343 if (!makeContextCurrent()) 344 return; 345 296 346 // The shader used to render layers returns pre-multiplied alpha colors 297 347 // so we need to send the blending mode appropriately. … … 299 349 glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA); 300 350 301 // Update the parameters for the checkerboard drawing.302 glUseProgram(m_checkerProgramObject);303 float bitmapScale = static_cast<float>(m_layoutRect.width()) / static_cast<float>(m_visibleRect.width());304 glUniform1f(m_checkerScaleLocation, bitmapScale);305 float scale = static_cast<float>(dstRect.width()) / static_cast<float>(m_visibleRect.width());306 glUniform2f(m_checkerOriginLocation, m_visibleRect.x()*scale, m_visibleRect.y()*scale);307 glUniform1f(m_checkerSurfaceHeightLocation, m_context->surfaceSize().height());308 309 checkGLError();310 311 351 // If some layers should be drawed on temporary surfaces, we should do it first. 312 352 drawLayersOnSurfaces(surfaceLayers); 313 314 #if ENABLE_SCISSOR315 m_scissorRect = m_viewport;316 glEnable(GL_SCISSOR_TEST);317 glScissor(m_scissorRect.x(), m_scissorRect.y(), m_scissorRect.width(), m_scissorRect.height());318 #endif319 320 glClearStencil(0);321 glClearColor(0, 0, 0, 0);322 GLenum buffersToClear = GL_STENCIL_BUFFER_BIT;323 if (m_clearSurfaceOnDrawLayers) {324 buffersToClear |= GL_COLOR_BUFFER_BIT;325 }326 glClear(buffersToClear);327 353 328 354 // Don't render the root layer, the BlackBerry port uses the BackingStore to draw the … … 330 356 for (size_t i = 0; i < sublayers.size(); i++) { 331 357 int currentStencilValue = 0; 332 FloatRect clipRect( -1, -1, 2, 2);358 FloatRect clipRect(m_clipRect); 333 359 compositeLayersRecursive(sublayers[i].get(), currentStencilValue, clipRect); 334 360 } … … 352 378 glBindTexture(GL_TEXTURE_2D, 0); 353 379 380 // Turn off blending again 381 glDisable(GL_BLEND); 382 354 383 LayerSet::iterator iter = m_layersLockingTextureResources.begin(); 355 384 for (; iter != m_layersLockingTextureResources.end(); ++iter) … … 360 389 if (m_needsCommit) { 361 390 m_needsCommit = false; 362 m_rootLayer->scheduleCommit();391 rootLayer->scheduleCommit(); 363 392 } 364 393 365 394 textureCacheCompositingThread()->collectGarbage(); 395 } 396 397 static float texcoords[4 * 2] = { 0, 0, 0, 1, 1, 1, 1, 0 }; 398 399 void LayerRenderer::compositeBuffer(const TransformationMatrix& transform, const FloatRect& contents, BlackBerry::Platform::Graphics::Buffer* buffer, float opacity) 400 { 401 if (!buffer) 402 return; 403 404 FloatQuad vertices(transform.mapPoint(contents.minXMinYCorner()), 405 transform.mapPoint(contents.minXMaxYCorner()), 406 transform.mapPoint(contents.maxXMaxYCorner()), 407 transform.mapPoint(contents.maxXMinYCorner())); 408 409 if (!vertices.boundingBox().intersects(m_clipRect)) 410 return; 411 412 if (opacity < 1.0f) { 413 glEnable(GL_BLEND); 414 glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA); 415 } 416 417 glUseProgram(m_layerProgramObject[LayerData::LayerProgramShaderRGBA]); 418 glUniform1f(m_alphaLocation[LayerData::LayerProgramShaderRGBA], opacity); 419 420 glVertexAttribPointer(m_positionLocation, 2, GL_FLOAT, GL_FALSE, 0, &vertices); 421 glVertexAttribPointer(m_texCoordLocation, 2, GL_FLOAT, GL_FALSE, 0, texcoords); 422 423 if (BlackBerry::Platform::Graphics::lockAndBindBufferGLTexture(buffer, GL_TEXTURE_2D)) { 424 glDrawArrays(GL_TRIANGLE_FAN, 0, 4); 425 BlackBerry::Platform::Graphics::releaseBufferGLTexture(buffer); 426 } 427 428 if (opacity < 1.0f) 429 glDisable(GL_BLEND); 430 } 431 432 void LayerRenderer::drawCheckerboardPattern(const TransformationMatrix& transform, const FloatRect& contents) 433 { 434 FloatQuad vertices(transform.mapPoint(contents.minXMinYCorner()), 435 transform.mapPoint(contents.minXMaxYCorner()), 436 transform.mapPoint(contents.maxXMaxYCorner()), 437 transform.mapPoint(contents.maxXMinYCorner())); 438 439 if (!vertices.boundingBox().intersects(m_clipRect)) 440 return; 441 442 glUseProgram(m_checkerProgramObject); 443 444 glVertexAttribPointer(m_positionLocation, 2, GL_FLOAT, GL_FALSE, 0, &vertices); 445 glVertexAttribPointer(m_texCoordLocation, 2, GL_FLOAT, GL_FALSE, 0, texcoords); 446 447 glDrawArrays(GL_TRIANGLE_FAN, 0, 4); 366 448 } 367 449 … … 416 498 // If there are layers drawed on surfaces, we need to switch to default framebuffer. 417 499 // Otherwise, we just need to set viewport. 418 if (surfaceLayers.size()) 500 if (surfaceLayers.size()) { 419 501 useSurface(0); 420 else 421 glViewport(m_viewport.x(), m_viewport.y(), m_viewport.width(), m_viewport.height()); 422 } 423 424 void LayerRenderer::setRootLayer(LayerCompositingThread* layer) 425 { 426 m_rootLayer = layer; 502 #if ENABLE_SCISSOR 503 glEnable(GL_SCISSOR_TEST); 504 glScissor(m_scissorRect.x(), m_scissorRect.y(), m_scissorRect.width(), m_scissorRect.height()); 505 #endif 506 } 427 507 } 428 508 … … 527 607 } 528 608 529 void LayerRenderer::updateLayersRecursive(LayerCompositingThread* layer, const TransformationMatrix& matrix, Vector<RefPtr<LayerCompositingThread> >& surfaceLayers, float opacity, FloatRect clipRect, double currentTime) 530 { 531 609 void LayerRenderer::prepareFrameRecursive(LayerCompositingThread* layer, double animationTime, bool isContextCurrent) 610 { 611 // This might cause the layer to recompute some attributes. 612 m_lastRenderingResults.needsAnimationFrame |= layer->updateAnimations(animationTime); 613 614 if (isContextCurrent) { 615 // Even non-visible layers need to perform their texture jobs, or they will 616 // pile up and waste memory. 617 if (layer->needsTexture()) 618 layer->updateTextureContentsIfNeeded(); 619 if (layer->maskLayer() && layer->maskLayer()->needsTexture()) 620 layer->maskLayer()->updateTextureContentsIfNeeded(); 621 if (layer->replicaLayer()) { 622 LayerCompositingThread* replica = layer->replicaLayer(); 623 if (replica->needsTexture()) 624 replica->updateTextureContentsIfNeeded(); 625 if (replica->maskLayer() && replica->maskLayer()->needsTexture()) 626 replica->maskLayer()->updateTextureContentsIfNeeded(); 627 } 628 } 629 630 const Vector<RefPtr<LayerCompositingThread> >& sublayers = layer->getSublayers(); 631 for (size_t i = 0; i < sublayers.size(); i++) 632 prepareFrameRecursive(sublayers[i].get(), animationTime, isContextCurrent); 633 } 634 635 void LayerRenderer::updateLayersRecursive(LayerCompositingThread* layer, const TransformationMatrix& matrix, Vector<RefPtr<LayerCompositingThread> >& surfaceLayers, float opacity, FloatRect clipRect) 636 { 532 637 // The contract for LayerCompositingThread::setLayerRenderer is it must be set if the layer has been rendered. 533 638 // So do it now, before we render it in compositeLayersRecursive. … … 541 646 replica->maskLayer()->setLayerRenderer(this); 542 647 } 543 544 // This might cause the layer to recompute some attributes.545 m_lastRenderingResults.needsAnimationFrame |= layer->updateAnimations(currentTime);546 648 547 649 // Compute the new matrix transformation that will be applied to this layer and … … 682 784 const Vector<RefPtr<LayerCompositingThread> >& sublayers = layer->getSublayers(); 683 785 for (size_t i = 0; i < sublayers.size(); i++) 684 updateLayersRecursive(sublayers[i].get(), localMatrix, surfaceLayers, opacity, clipRect , currentTime);786 updateLayersRecursive(sublayers[i].get(), localMatrix, surfaceLayers, opacity, clipRect); 685 787 } 686 788 … … 731 833 // 1. Layers that have their own GraphicsContext and can draw their contents on demand (layer->drawsContent() == true). 732 834 // 2. Layers that are just containers of images/video/etc that don't own a GraphicsContext (layer->contents() == true). 733 734 // Even non-visible layers need to perform their texture jobs, or they will735 // pile up and waste memory.736 if (layer->needsTexture())737 layer->updateTextureContentsIfNeeded();738 if (layer->maskLayer() && layer->maskLayer()->needsTexture())739 layer->maskLayer()->updateTextureContentsIfNeeded();740 if (layer->replicaLayer()) {741 LayerCompositingThread* replica = layer->replicaLayer();742 if (replica->needsTexture())743 replica->updateTextureContentsIfNeeded();744 if (replica->maskLayer() && replica->maskLayer()->needsTexture())745 replica->maskLayer()->updateTextureContentsIfNeeded();746 }747 835 748 836 if ((layer->needsTexture() || layer->layerRendererSurface()) && layerVisible) { … … 871 959 { 872 960 #if ENABLE_SCISSOR 961 #if DEBUG_CLIPPING 962 printf("LayerRenderer::updateScissorIfNeeded(): clipRect=(%.2f,%.2f %.2fx%.2f)\n", clipRect.x(), clipRect.y(), clipRect.width(), clipRect.height()); 963 fflush(stdout); 964 #endif 873 965 IntRect clipRectWC = toOpenGLWindowCoordinates(clipRect); 874 966 if (m_scissorRect == clipRectWC) … … 876 968 877 969 m_scissorRect = clipRectWC; 970 #if DEBUG_CLIPPING 971 printf("LayerRenderer::updateScissorIfNeeded(): clipping to (%d,%d %dx%d)\n", m_scissorRect.x(), m_scissorRect.y(), m_scissorRect.width(), m_scissorRect.height()); 972 fflush(stdout); 973 #endif 878 974 glScissor(m_scissorRect.x(), m_scissorRect.y(), m_scissorRect.width(), m_scissorRect.height()); 879 975 #endif … … 1093 1189 void LayerRenderingResults::addHolePunchRect(const IntRect& rect) 1094 1190 { 1095 #if DEBUG_VIDEO_CLIPPING 1096 BlackBerry::Platform::log(BlackBerry::Platform::LogLevelInfo, "LayerRenderingResults::addHolePunchRect (x=%d,y=%d,width=%d,height=%d).", rect.x(), rect.y(), rect.width(), rect.height()); 1191 #if DEBUG_CLIPPING 1192 printf("LayerRenderingResults::addHolePunchRect (%d,%d %dx%d)\n", rect.x(), rect.y(), rect.width(), rect.height()); 1193 fflush(stdout); 1097 1194 #endif 1098 1195 if (!rect.isEmpty()) -
trunk/Source/WebCore/platform/graphics/blackberry/LayerRenderer.h
r109908 r118696 80 80 WTF_MAKE_NONCOPYABLE(LayerRenderer); 81 81 public: 82 static TransformationMatrix orthoMatrix(float left, float right, float bottom, float top, float nearZ, float farZ); 83 82 84 static PassOwnPtr<LayerRenderer> create(BlackBerry::Platform::Graphics::GLES2Context*); 83 85 … … 87 89 void releaseLayerResources(); 88 90 89 // Recomposites all the layers. Returns true if it needs more draw. 90 void drawLayers(const FloatRect& visibleRect, const IntRect& layoutRect, const IntSize& contentsSize, const IntRect& dstRect); 91 92 void setRootLayer(LayerCompositingThread*); 93 LayerCompositingThread* rootLayer() { return m_rootLayer.get(); } 91 // In order to render the layers, you must do the following 3 operations, in order. 92 93 // 1. Upload textures and other operations that should be performed at the beginning of each frame. 94 // Note, this call also resets the last rendering results. 95 void prepareFrame(double animationTime, LayerCompositingThread* rootLayer); 96 97 // 2. Set the OpenGL viewport and store other viewport-related parameters 98 // viewport is the GL viewport 99 // clipRect is an additional clip rect, if clipping is required beyond the clipping effect of the viewport. 100 // visibleRect is the subrect of the web page that you wish to composite, expressed in content coordinates 101 // The last two parameters are required to draw fixed position elements in the right place: 102 // layoutRect is the subrect of the web page that the WebKit thread believes is visible (scroll position, actual visible size). 103 // contentsSize is the contents size of the web page 104 void setViewport(const IntRect& viewport, const IntRect& clipRect, const FloatRect& visibleRect, const IntRect& layoutRect, const IntSize& contentsSize); 105 106 // 3. Prepares all the layers for compositing 107 // transform is the model-view-project matrix that goes all the way from contents to normalized device coordinates. 108 void compositeLayers(const TransformationMatrix&, LayerCompositingThread* rootLayer); 109 void compositeBuffer(const TransformationMatrix&, const FloatRect& contents, BlackBerry::Platform::Graphics::Buffer*, float opacity); 110 void drawCheckerboardPattern(const TransformationMatrix&, const FloatRect& contents); 94 111 95 112 // Keep track of layers that need cleanup when the LayerRenderer is destroyed … … 119 136 120 137 private: 121 void updateLayersRecursive(LayerCompositingThread*, const TransformationMatrix& parentMatrix, Vector<RefPtr<LayerCompositingThread> >& surfaceLayers, float opacity, FloatRect clipRect, double currentTime); 138 void prepareFrameRecursive(LayerCompositingThread*, double animationTime, bool isContextCurrent); 139 void updateLayersRecursive(LayerCompositingThread*, const TransformationMatrix& parentMatrix, Vector<RefPtr<LayerCompositingThread> >& surfaceLayers, float opacity, FloatRect clipRect); 122 140 void compositeLayersRecursive(LayerCompositingThread*, int stencilValue, FloatRect clipRect); 123 141 void updateScissorIfNeeded(const FloatRect& clipRect); … … 159 177 160 178 // Current draw configuration. 179 double m_animationTime; 161 180 FloatRect m_visibleRect; 162 181 IntRect m_layoutRect; 163 182 IntSize m_contentsSize; 164 183 165 IntRect m_viewport; 166 IntRect m_scissorRect; 167 168 RefPtr<LayerCompositingThread> m_rootLayer; 184 IntRect m_viewport; // In render target coordinates 185 IntRect m_scissorRect; // In render target coordinates 186 FloatRect m_clipRect; // In normalized device coordinates 169 187 170 188 unsigned m_fbo; -
trunk/Source/WebKit/blackberry/Api/BackingStore.cpp
r118626 r118696 1029 1029 #endif 1030 1030 1031 bool blittingDirectlyToCompositingWindow = isOpenGLCompositing();1032 1033 1031 BackingStoreGeometry* currentState = frontState(); 1034 1032 TileMap currentMap = currentState->tileMap(); … … 1079 1077 = tile->backBuffer()->nativeBuffer(); 1080 1078 1081 if (blittingDirectlyToCompositingWindow) { 1079 // This code is only needed for EGLImage code path, and only effective if we are swapping the render target. 1080 // This combination is only true if there's a GLES2Usage window. 1081 // FIXME: Use an EGL fence instead, PR152132 1082 Window* window = m_webPage->client()->window(); 1083 if (window && window->windowUsage() == Window::GLES2Usage) { 1082 1084 pthread_mutex_lock(&m_blitGenerationLock); 1083 1085 while (m_blitGeneration == tile->backBuffer()->blitGeneration()) { … … 1533 1535 } 1534 1536 1535 bool blittingDirectlyToCompositingWindow = isOpenGLCompositing();1536 1537 1537 #if USE(ACCELERATED_COMPOSITING) 1538 1538 if (WebPageCompositorPrivate* compositor = m_webPage->d->compositor()) { … … 1543 1543 } 1544 1544 1545 if (! blittingDirectlyToCompositingWindow)1545 if (!isOpenGLCompositing()) 1546 1546 blendCompositingSurface(dstRect); 1547 1547 #endif … … 1605 1605 invalidateWindow(dstRect); 1606 1606 1607 if (blittingDirectlyToCompositingWindow && !blittedTiles.isEmpty()) { 1607 // This code is only needed for EGLImage code path, and only effective if we are swapping the render target. 1608 // This combination is only true if there's a GLES2Usage window. 1609 // FIXME: Use an EGL fence instead 1610 Window* window = m_webPage->client()->window(); 1611 if (window && window->windowUsage() == Window::GLES2Usage && !blittedTiles.isEmpty()) { 1608 1612 pthread_mutex_lock(&m_blitGenerationLock); 1609 1613 … … 1623 1627 } 1624 1628 } 1629 1630 #if USE(ACCELERATED_COMPOSITING) 1631 void BackingStorePrivate::compositeContents(WebCore::LayerRenderer* layerRenderer, const WebCore::TransformationMatrix& transform, const WebCore::FloatRect& contents) 1632 { 1633 const Platform::IntRect transformedContentsRect = Platform::IntRect(Platform::IntPoint(0, 0), m_client->transformedContentsSize()); 1634 Platform::IntRect transformedContents = enclosingIntRect(m_webPage->d->m_transformationMatrix->mapRect(contents)); 1635 transformedContents.intersect(transformedContentsRect); 1636 if (transformedContents.isEmpty()) 1637 return; 1638 1639 if (!isActive()) 1640 return; 1641 1642 if (m_webPage->d->compositorDrawsRootLayer()) 1643 return; 1644 1645 BackingStoreGeometry* currentState = frontState(); 1646 TileMap currentMap = currentState->tileMap(); 1647 1648 Platform::IntRectRegion transformedContentsRegion = transformedContents; 1649 Platform::IntRectRegion backingStoreRegion = currentState->backingStoreRect(); 1650 Platform::IntRectRegion checkeredRegion 1651 = Platform::IntRectRegion::subtractRegions(transformedContentsRegion, backingStoreRegion); 1652 1653 // Blit checkered to those parts that are not covered by the backingStoreRect. 1654 IntRectList checkeredRects = checkeredRegion.rects(); 1655 for (size_t i = 0; i < checkeredRects.size(); ++i) 1656 layerRenderer->drawCheckerboardPattern(transform, m_webPage->d->mapFromTransformedFloatRect(WebCore::IntRect(checkeredRects.at(i)))); 1657 1658 // Get the list of tile rects that makeup the content. 1659 TileRectList tileRectList = mapFromTransformedContentsToTiles(transformedContents, currentState); 1660 for (size_t i = 0; i < tileRectList.size(); ++i) { 1661 TileRect tileRect = tileRectList[i]; 1662 TileIndex index = tileRect.first; 1663 Platform::IntRect dirtyTileRect = tileRect.second; 1664 BackingStoreTile* tile = currentMap.get(index); 1665 TileBuffer* tileBuffer = tile->frontBuffer(); 1666 1667 // This dirty rect is in tile coordinates, but it needs to be in 1668 // transformed contents coordinates. 1669 Platform::IntRect dirtyRect = mapFromTilesToTransformedContents(tileRect, currentState->backingStoreRect()); 1670 1671 if (!dirtyRect.intersects(transformedContents)) 1672 continue; 1673 1674 TileRect wholeTileRect; 1675 wholeTileRect.first = index; 1676 wholeTileRect.second = this->tileRect(); 1677 1678 Platform::IntRect wholeRect = mapFromTilesToTransformedContents(wholeTileRect, currentState->backingStoreRect()); 1679 1680 bool committed = tile->isCommitted(); 1681 1682 if (!committed) 1683 layerRenderer->drawCheckerboardPattern(transform, m_webPage->d->mapFromTransformedFloatRect(Platform::FloatRect(dirtyRect))); 1684 else { 1685 layerRenderer->compositeBuffer(transform, m_webPage->d->mapFromTransformedFloatRect(Platform::FloatRect(wholeRect)), tileBuffer->nativeBuffer(), 1.0f); 1686 1687 // Intersect the rendered region. 1688 Platform::IntRectRegion notRenderedRegion = Platform::IntRectRegion::subtractRegions(dirtyTileRect, tileBuffer->renderedRegion()); 1689 IntRectList notRenderedRects = notRenderedRegion.rects(); 1690 for (size_t i = 0; i < notRenderedRects.size(); ++i) 1691 layerRenderer->drawCheckerboardPattern(transform, m_webPage->d->mapFromTransformedFloatRect(Platform::FloatRect(notRenderedRects.at(i)))); 1692 } 1693 } 1694 } 1695 #endif 1625 1696 1626 1697 Platform::IntRect BackingStorePrivate::blitTileRect(TileBuffer* tileBuffer, -
trunk/Source/WebKit/blackberry/Api/BackingStore_p.h
r117223 r118696 33 33 namespace WebCore { 34 34 class IntRect; 35 class FloatRect; 36 class LayerRenderer; 35 37 class TransformationMatrix; 36 38 } … … 197 199 198 200 #if USE(ACCELERATED_COMPOSITING) 201 // Use instead of blitContents if you need more control over OpenGL state. 202 // Note that contents is expressed in untransformed content coordinates. 203 // Preconditions: You have to call prepareFrame and setViewport on the LayerRenderer before 204 // calling this. 205 void compositeContents(WebCore::LayerRenderer*, const WebCore::TransformationMatrix&, const WebCore::FloatRect& contents); 206 199 207 void blendCompositingSurface(const Platform::IntRect& dstRect); 200 208 void clearCompositingSurface(); 209 201 210 bool drawLayersOnCommitIfNeeded(); 202 211 void drawAndBlendLayersForDirectRendering(const Platform::IntRect& dirtyRect); -
trunk/Source/WebKit/blackberry/Api/WebPageCompositor.cpp
r118627 r118696 35 35 #include <GenericTimerClient.h> 36 36 #include <ThreadTimerClient.h> 37 #include <wtf/CurrentTime.h> 37 38 38 39 using namespace WebCore; … … 66 67 67 68 m_layerRenderer = LayerRenderer::create(m_context); 68 m_layerRenderer->setRootLayer(m_rootLayer.get());69 69 } 70 70 … … 77 77 { 78 78 m_rootLayer = rootLayer; 79 80 if (m_layerRenderer) 81 m_layerRenderer->setRootLayer(m_rootLayer.get()); 82 } 83 84 void WebPageCompositorPrivate::commit(LayerWebKitThread* rootLayer) 85 { 86 if (!rootLayer) 87 return; 88 89 rootLayer->commitOnCompositingThread(); 90 } 91 92 void WebPageCompositorPrivate::render(const IntRect& dstRect, const IntRect& transformedContents) 93 { 94 // It's not safe to call into the BackingStore if the compositor hasn't been set yet. 95 // For thread safety, we have to do it using a round-trip to the WebKit thread, so the 96 // embedder might call this before the round-trip to WebPagePrivate::setCompositor() is 97 // done. 98 if (m_webPage->compositor() != this) 99 return; 100 101 // The BackingStore is the root layer 102 if (BackingStore* backingStore = m_webPage->m_backingStore) 103 backingStore->d->blitContents(dstRect, transformedContents, true); 104 else { 105 FloatRect contents = m_webPage->mapFromTransformedFloatRect(FloatRect(transformedContents)); 106 drawLayers(dstRect, contents); 79 } 80 81 void WebPageCompositorPrivate::prepareFrame(double animationTime) 82 { 83 if (!m_layerRenderer) 84 return; 85 86 // Unfortunately, we have to use currentTime() because the animations are 87 // started in that time coordinate system. 88 animationTime = currentTime(); 89 if (m_rootLayer) 90 m_layerRenderer->prepareFrame(animationTime, m_rootLayer.get()); 91 } 92 93 void WebPageCompositorPrivate::render(const IntRect& targetRect, const IntRect& clipRect, const TransformationMatrix& transformIn, const FloatRect& transformedContents, const FloatRect& /*viewport*/) 94 { 95 if (!m_layerRenderer) { 96 // It's not safe to call into the BackingStore if the compositor hasn't been set yet. 97 // For thread safety, we have to do it using a round-trip to the WebKit thread, so the 98 // embedder might call this before the round-trip to WebPagePrivate::setCompositor() is 99 // done. 100 if (m_webPage->compositor() != this) 101 return; 102 103 // The clip rect is in OpenGL coordinate system, so turn it upside down to get to window coordinates. 104 IntRect dstRect(clipRect.x(), m_context->surfaceSize().height() - clipRect.y() - clipRect.height(), clipRect.width(), clipRect.height()); 105 m_webPage->m_backingStore->d->blitContents(dstRect, enclosingIntRect(transformedContents), true); 106 return; 107 } 108 109 m_layerRenderer->setClearSurfaceOnDrawLayers(false); 110 111 FloatRect contents = m_webPage->mapFromTransformedFloatRect(transformedContents); 112 113 m_layerRenderer->setViewport(targetRect, clipRect, contents, m_layoutRectForCompositing, m_contentsSizeForCompositing); 114 115 TransformationMatrix transform(transformIn); 116 transform *= *m_webPage->m_transformationMatrix; 117 118 if (!drawsRootLayer()) 119 m_webPage->m_backingStore->d->compositeContents(m_layerRenderer.get(), transform, contents); 120 121 if (m_rootLayer) 122 m_layerRenderer->compositeLayers(transform, m_rootLayer.get()); 123 124 m_lastCompositingResults = m_layerRenderer->lastRenderingResults(); 125 126 if (m_lastCompositingResults.needsAnimationFrame) { 127 Platform::AnimationFrameRateController::instance()->addClient(this); 128 m_webPage->updateDelegatedOverlays(); 107 129 } 108 130 } … … 123 145 m_layerRenderer->setClearSurfaceOnDrawLayers(shouldClear); 124 146 125 m_layerRenderer->drawLayers(contents, m_layoutRectForCompositing, m_contentsSizeForCompositing, dstRect); 147 // OpenGL window coordinates origin is at the lower left corner of the surface while 148 // WebKit uses upper left as the origin of the window coordinate system. The passed in 'dstRect' 149 // is in WebKit window coordinate system. Here we setup the viewport to the corresponding value 150 // in OpenGL window coordinates. 151 m_layerRenderer->prepareFrame(currentTime(), m_rootLayer.get()); 152 int viewportY = std::max(0, m_context->surfaceSize().height() - dstRect.maxY()); 153 IntRect viewport = IntRect(dstRect.x(), viewportY, dstRect.width(), dstRect.height()); 154 155 m_layerRenderer->setViewport(viewport, viewport, contents, m_layoutRectForCompositing, m_contentsSizeForCompositing); 156 157 // WebKit uses row vectors which are multiplied by the matrix on the left (i.e. v*M) 158 // Transformations are composed on the left so that M1.xform(M2) means M2*M1 159 // We therefore start with our (othogonal) projection matrix, which will be applied 160 // as the last transformation. 161 TransformationMatrix transform = LayerRenderer::orthoMatrix(0, contents.width(), contents.height(), 0, -1000, 1000); 162 transform.translate3d(-contents.x(), -contents.y(), 0); 163 if (m_rootLayer) 164 m_layerRenderer->compositeLayers(transform, m_rootLayer.get()); 165 126 166 m_lastCompositingResults = m_layerRenderer->lastRenderingResults(); 127 167 … … 203 243 } 204 244 205 void WebPageCompositor::prepareFrame(Platform::Graphics::GLES2Context* context, double timestamp)245 void WebPageCompositor::prepareFrame(Platform::Graphics::GLES2Context* context, double animationTime) 206 246 { 207 247 d->setContext(context); 208 } 209 210 void WebPageCompositor::render(Platform::Graphics::GLES2Context* context, const Platform::IntRect& dstRect, const Platform::IntRect& contents) 248 d->prepareFrame(animationTime); 249 } 250 251 void WebPageCompositor::render(Platform::Graphics::GLES2Context* context, 252 const Platform::IntRect& targetRect, 253 const Platform::IntRect& clipRect, 254 const Platform::TransformationMatrix& transform, 255 const Platform::FloatRect& contents, 256 const Platform::FloatRect& viewport) 211 257 { 212 258 d->setContext(context); 213 d->render( dstRect, contents);259 d->render(targetRect, clipRect, TransformationMatrix(reinterpret_cast<const TransformationMatrix&>(transform)), contents, viewport); 214 260 } 215 261 … … 253 299 } 254 300 255 void WebPageCompositor::render(Platform::Graphics::GLES2Context*, const Platform::IntRect&, const Platform::IntRect&) 301 void WebPageCompositor::render(Platform::Graphics::GLES2Context*, 302 const Platform::IntRect&, 303 const Platform::IntRect&, 304 const Platform::TransformationMatrix&, 305 const Platform::FloatRect&, 306 const Platform::FloatRect&) 256 307 { 257 308 } -
trunk/Source/WebKit/blackberry/Api/WebPageCompositor.h
r111959 r118696 40 40 WebPageCompositorClient* client() const; 41 41 42 void prepareFrame(Platform::Graphics::GLES2Context*, double timestamp);42 void prepareFrame(Platform::Graphics::GLES2Context*, double animationTime); 43 43 44 // FIXME: dstRect should be a Platform::TransformationMatrix instead. PR142628 45 void render(Platform::Graphics::GLES2Context*, const Platform::IntRect& dstRect, const Platform::IntRect& contents); 44 void render(Platform::Graphics::GLES2Context*, 45 const Platform::IntRect& targetRect, 46 const Platform::IntRect& clipRect, 47 const Platform::TransformationMatrix&, 48 const Platform::FloatRect& contents, 49 const Platform::FloatRect& viewport); 46 50 47 51 void cleanup(Platform::Graphics::GLES2Context*); -
trunk/Source/WebKit/blackberry/Api/WebPageCompositorClient.h
r111959 r118696 33 33 virtual double requestAnimationFrame() = 0; 34 34 virtual void invalidate(double animationFrameTimestamp) = 0; 35 virtual void requestCleanup() = 0;36 35 }; 37 36 -
trunk/Source/WebKit/blackberry/Api/WebPageCompositor_p.h
r118627 r118696 51 51 ~WebPageCompositorPrivate(); 52 52 53 // Public API 54 void prepareFrame(double animationTime); 55 void render(const WebCore::IntRect& targetRect, 56 const WebCore::IntRect& clipRect, 57 const WebCore::TransformationMatrix&, 58 const WebCore::FloatRect& contents, // This is public API, thus takes transformed contents 59 const WebCore::FloatRect& viewport); 60 61 // Internal 53 62 bool hardwareCompositing() const; 54 63 … … 59 68 void setRootLayer(WebCore::LayerCompositingThread*); 60 69 61 void commit(WebCore::LayerWebKitThread* rootLayerProxy);62 63 // This is mapped from the public API, thus takes transformed contents64 void render(const WebCore::IntRect& dstRect, const WebCore::IntRect& transformedContents);65 66 // Returns true if the WebPageCompositor draws the root layer, false if the BackingStore draws the root layer67 70 bool drawsRootLayer() const; 68 71 void setDrawsRootLayer(bool drawsRootLayer) { m_drawsRootLayer = drawsRootLayer; } -
trunk/Source/WebKit/blackberry/ChangeLog
r118689 r118696 1 2012-05-28 Arvid Nilsson <anilsson@rim.com> 2 3 [BlackBerry] Update WebPageCompositor::render() API 4 https://bugs.webkit.org/show_bug.cgi?id=87565 5 6 Reviewed by Rob Buis. 7 8 The new API allows the embedder to specify the root transform and many 9 OpenGL related parameters to be used when rendering the web page. 10 11 To honor the transform, we have to implement a way to composite the 12 BackingStore output using a generic transform. This method, 13 BackingStorePrivate::compositeContents(), uses a strategy that differs 14 from blitContents(), because that one is optimized for software 15 blitting, while this one is optimized for GPU rendering. Specifically, 16 instead of drawing the checkerboard first, and the rendered subregions 17 of the tile afterward, we draw the whole tile in one call, and then 18 draw checkered regions on top, if any. 19 20 Removed the blit generation condvar from the new code paths for drawing 21 BackingStore output using a transform, since the condvar is ineffective 22 in preventing flicker when we're not in charge of swapping the window. 23 Instead, another synchronization solution will be implemented in the 24 future. 25 26 Reviewed internally by Filip Spacek. 27 Some parts reviewed internally by Jacky Jiang and others by 28 Mike Lattanzio. 29 30 PR #151887, #154334 31 32 * Api/BackingStore.cpp: 33 (BlackBerry::WebKit::BackingStorePrivate::render): 34 (BlackBerry::WebKit::BackingStorePrivate::blitContents): 35 (WebKit): 36 (BlackBerry::WebKit::BackingStorePrivate::compositeContents): 37 * Api/BackingStore_p.h: 38 (WebCore): 39 (BackingStorePrivate): 40 * Api/WebPageCompositor.cpp: 41 (BlackBerry::WebKit::WebPageCompositorPrivate::setContext): 42 (BlackBerry::WebKit::WebPageCompositorPrivate::setRootLayer): 43 (BlackBerry::WebKit::WebPageCompositorPrivate::prepareFrame): 44 (BlackBerry::WebKit::WebPageCompositorPrivate::render): 45 (BlackBerry::WebKit::WebPageCompositorPrivate::drawLayers): 46 (BlackBerry::WebKit::WebPageCompositor::prepareFrame): 47 (BlackBerry::WebKit::WebPageCompositor::render): 48 * Api/WebPageCompositor.h: 49 * Api/WebPageCompositorClient.h: 50 * Api/WebPageCompositor_p.h: 51 (WebPageCompositorPrivate): 52 * WebCoreSupport/ChromeClientBlackBerry.cpp: 53 1 54 2012-05-28 Arvid Nilsson <anilsson@rim.com> 2 55 -
trunk/Source/WebKit/blackberry/WebCoreSupport/ChromeClientBlackBerry.cpp
r117148 r118696 37 37 #include "Geolocation.h" 38 38 #include "GeolocationControllerClientBlackBerry.h" 39 #include "GraphicsLayer.h" 39 40 #include "HTMLInputElement.h" 40 41 #include "HTMLNames.h"
Note: See TracChangeset
for help on using the changeset viewer.