Patch by James Robinson <jamesr@chromium.org> on 2011-07-13
[WebKit-https.git] / Source / WebCore / platform / graphics / chromium / LayerRendererChromium.cpp
1 /*
2  * Copyright (C) 2010 Google Inc. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions are
6  * met:
7  *
8  *     * Redistributions of source code must retain the above copyright
9  * notice, this list of conditions and the following disclaimer.
10  *     * Redistributions in binary form must reproduce the above
11  * copyright notice, this list of conditions and the following disclaimer
12  * in the documentation and/or other materials provided with the
13  * distribution.
14  *     * Neither the name of Google Inc. nor the names of its
15  * contributors may be used to endorse or promote products derived from
16  * this software without specific prior written permission.
17  *
18  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29  */
30
31
32 #include "config.h"
33
34 #if USE(ACCELERATED_COMPOSITING)
35 #include "LayerRendererChromium.h"
36
37 #include "Canvas2DLayerChromium.h"
38 #include "Extensions3DChromium.h"
39 #include "FloatQuad.h"
40 #include "GeometryBinding.h"
41 #include "GraphicsContext3D.h"
42 #include "LayerChromium.h"
43 #include "LayerPainterChromium.h"
44 #include "LayerTexture.h"
45 #include "LayerTextureUpdaterCanvas.h"
46 #include "NotImplemented.h"
47 #include "TextStream.h"
48 #include "TextureManager.h"
49 #include "TreeSynchronizer.h"
50 #include "TraceEvent.h"
51 #include "WebGLLayerChromium.h"
52 #include "cc/CCLayerImpl.h"
53 #include "cc/CCLayerTreeHostImpl.h"
54 #include "cc/CCMainThreadTask.h"
55 #if USE(SKIA)
56 #include "Extensions3D.h"
57 #include "GrContext.h"
58 #include "NativeImageSkia.h"
59 #include "PlatformContextSkia.h"
60 #elif USE(CG)
61 #include <CoreGraphics/CGBitmapContext.h>
62 #endif
63 #include <wtf/CurrentTime.h>
64
65 namespace WebCore {
66
67 // FIXME: Make this limit adjustable and give it a useful value.
68
69 // Absolute maximum limit for texture allocations for this instance.
70 static size_t textureMemoryHighLimitBytes = 128 * 1024 * 1024;
71 // Preferred texture size limit. Can be exceeded if needed.
72 static size_t textureMemoryReclaimLimitBytes = 64 * 1024 * 1024;
73 // The maximum texture memory usage when asked to release textures.
74 static size_t textureMemoryLowLimitBytes = 3 * 1024 * 1024;
75
76 #ifndef NDEBUG
77 bool LayerRendererChromium::s_inPaintLayerContents = false;
78 #endif
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 buffer
93     // 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_contextSupportsLatch(false)
136     , m_contextSupportsTextureFormatBGRA(false)
137     , m_contextSupportsReadFormatBGRA(false)
138     , m_animating(false)
139     , m_defaultRenderSurface(0)
140 {
141     WebCore::Extensions3D* extensions = m_context->getExtensions();
142     m_contextSupportsLatch = extensions->supports("GL_CHROMIUM_latch");
143     m_contextSupportsMapSub = extensions->supports("GL_CHROMIUM_map_sub");
144     if (m_contextSupportsMapSub)
145         extensions->ensureEnabled("GL_CHROMIUM_map_sub");
146     m_contextSupportsTextureFormatBGRA = extensions->supports("GL_EXT_texture_format_BGRA8888");
147     if (m_contextSupportsTextureFormatBGRA)
148         extensions->ensureEnabled("GL_EXT_texture_format_BGRA8888");
149     m_contextSupportsReadFormatBGRA = extensions->supports("GL_EXT_read_format_bgra");
150     if (m_contextSupportsReadFormatBGRA)
151         extensions->ensureEnabled("GL_EXT_read_format_bgra");
152
153 #if USE(SKIA)
154     m_accelerateDrawing = accelerateDrawing && skiaContext();
155 #endif
156     m_hardwareCompositing = initializeSharedObjects();
157
158 #if USE(SKIA)
159     if (m_accelerateDrawing)
160         m_rootLayerTextureUpdater = LayerTextureUpdaterSkPicture::create(m_context.get(), contentPaint, skiaContext());
161     else
162 #endif
163         m_rootLayerTextureUpdater = LayerTextureUpdaterBitmap::create(m_context.get(), contentPaint, m_contextSupportsMapSub);
164
165     m_rootLayerContentTiler = LayerTilerChromium::create(this, IntSize(256, 256), LayerTilerChromium::NoBorderTexels);
166     ASSERT(m_rootLayerContentTiler);
167
168     m_headsUpDisplay = CCHeadsUpDisplay::create(this);
169 }
170
171 LayerRendererChromium::~LayerRendererChromium()
172 {
173     m_headsUpDisplay.clear(); // Explicitly destroy the HUD before the TextureManager dies.
174     cleanupSharedObjects();
175 }
176
177 GraphicsContext3D* LayerRendererChromium::context()
178 {
179     return m_context.get();
180 }
181
182 #if USE(SKIA)
183 GrContext* LayerRendererChromium::skiaContext()
184 {
185     if (!m_skiaContext && m_contextSupportsTextureFormatBGRA && m_contextSupportsReadFormatBGRA) {
186         m_context->makeContextCurrent();
187         m_skiaContext = adoptPtr(GrContext::CreateGLShaderContext());
188         // Limit the number of textures we hold in the bitmap->texture cache.
189         static const int maxTextureCacheCount = 512;
190         // Limit the bytes allocated toward textures in the bitmap->texture cache.
191         static const size_t maxTextureCacheBytes = 50 * 1024 * 1024;
192         m_skiaContext->setTextureCacheLimits(maxTextureCacheCount, maxTextureCacheBytes);
193     }
194     return m_skiaContext.get();
195 }
196 #endif
197
198 void LayerRendererChromium::debugGLCall(GraphicsContext3D* context, const char* command, const char* file, int line)
199 {
200     unsigned long error = context->getError();
201     if (error != GraphicsContext3D::NO_ERROR)
202         LOG_ERROR("GL command failed: File: %s\n\tLine %d\n\tcommand: %s, error %x\n", file, line, command, static_cast<int>(error));
203 }
204
205 void LayerRendererChromium::invalidateRootLayerRect(const IntRect& dirtyRect)
206 {
207     m_rootLayerContentTiler->invalidateRect(dirtyRect);
208 }
209
210 void LayerRendererChromium::releaseTextures()
211 {
212     // Reduces texture memory usage to textureMemoryLowLimitBytes by deleting non root layer
213     // textures.
214     m_rootLayerContentTiler->protectTileTextures(m_viewportVisibleRect);
215     m_textureManager->reduceMemoryToLimit(textureMemoryLowLimitBytes);
216     m_textureManager->unprotectAllTextures();
217 }
218
219 void LayerRendererChromium::updateRootLayerContents()
220 {
221     TRACE_EVENT("LayerRendererChromium::updateRootLayerContents", this, 0);
222     m_rootLayerContentTiler->prepareToUpdate(m_viewportVisibleRect, m_rootLayerTextureUpdater.get());
223 }
224
225 void LayerRendererChromium::drawRootLayer()
226 {
227     TransformationMatrix scroll;
228     scroll.translate(-m_viewportVisibleRect.x(), -m_viewportVisibleRect.y());
229
230     m_rootLayerContentTiler->draw(m_viewportVisibleRect, scroll, 1.0f);
231 }
232
233 void LayerRendererChromium::setViewport(const IntRect& visibleRect, const IntRect& contentRect, const IntPoint& scrollPosition)
234 {
235     bool visibleRectChanged = m_viewportVisibleRect.size() != visibleRect.size();
236
237     m_viewportVisibleRect = visibleRect;
238     m_viewportContentRect = contentRect;
239     m_viewportScrollPosition = scrollPosition;
240
241     if (visibleRectChanged) {
242         // Reset the current render surface to force an update of the viewport and
243         // projection matrix next time useRenderSurface is called.
244         m_currentRenderSurface = 0;
245         m_rootLayerContentTiler->invalidateEntireLayer();
246     }
247     setNeedsCommitAndRedraw();
248 }
249
250 void LayerRendererChromium::updateLayers()
251 {
252     if (m_viewportVisibleRect.isEmpty())
253         return;
254
255     // FIXME: use the frame begin time from the overall compositor scheduler.
256     // This value is currently inaccessible because it is up in Chromium's
257     // RenderWidget.
258     m_headsUpDisplay->onFrameBegin(currentTime());
259     ASSERT(m_hardwareCompositing);
260
261     if (!m_rootLayer)
262         return;
263
264     updateRootLayerContents();
265
266     // Recheck that we still have a root layer. This may become null if
267     // compositing gets turned off during a paint operation.
268     if (!m_rootLayer)
269         return;
270
271     {
272         TRACE_EVENT("LayerRendererChromium::synchronizeTrees", this, 0);
273         m_rootCCLayerImpl = TreeSynchronizer::synchronizeTrees(m_rootLayer.get(), m_rootCCLayerImpl.get());
274     }
275
276     m_computedRenderSurfaceLayerList = adoptPtr(new LayerList());
277     updateLayers(*m_computedRenderSurfaceLayerList);
278 }
279
280 void LayerRendererChromium::drawLayers()
281 {
282     ASSERT(m_hardwareCompositing);
283     ASSERT(m_computedRenderSurfaceLayerList);
284     // Before drawLayers:
285     if (hardwareCompositing() && m_contextSupportsLatch) {
286         // FIXME: The multithreaded compositor case will not work as long as
287         // copyTexImage2D resolves to the parent texture, because the main
288         // thread can execute WebGL calls on the child context at any time,
289         // potentially clobbering the parent texture that is being renderered
290         // by the compositor thread.
291         Extensions3DChromium* parentExt = static_cast<Extensions3DChromium*>(m_context->getExtensions());
292         // For each child context:
293         //   glWaitLatch(Offscreen->Compositor);
294         ChildContextMap::iterator i = m_childContexts.begin();
295         for (; i != m_childContexts.end(); ++i) {
296             Extensions3DChromium* childExt = static_cast<Extensions3DChromium*>(i->first->getExtensions());
297             if (childExt->getGraphicsResetStatusARB() == GraphicsContext3D::NO_ERROR) {
298                 GC3Duint childToParentLatchId;
299                 childExt->getChildToParentLatchCHROMIUM(&childToParentLatchId);
300                 childExt->setLatchCHROMIUM(childToParentLatchId);
301                 parentExt->waitLatchCHROMIUM(childToParentLatchId);
302             }
303         }
304     }
305
306     drawLayers(*m_computedRenderSurfaceLayerList);
307
308     m_textureManager->unprotectAllTextures();
309
310     // After drawLayers:
311     if (hardwareCompositing() && m_contextSupportsLatch) {
312         Extensions3DChromium* parentExt = static_cast<Extensions3DChromium*>(m_context->getExtensions());
313         // For each child context:
314         //   glSetLatch(Compositor->Offscreen);
315         ChildContextMap::iterator i = m_childContexts.begin();
316         for (; i != m_childContexts.end(); ++i) {
317             Extensions3DChromium* childExt = static_cast<Extensions3DChromium*>(i->first->getExtensions());
318             if (childExt->getGraphicsResetStatusARB() == GraphicsContext3D::NO_ERROR) {
319                 GC3Duint parentToChildLatchId;
320                 childExt->getParentToChildLatchCHROMIUM(&parentToChildLatchId);
321                 parentExt->setLatchCHROMIUM(parentToChildLatchId);
322                 childExt->waitLatchCHROMIUM(parentToChildLatchId);
323             }
324         }
325     }
326
327     if (isCompositingOffscreen())
328         copyOffscreenTextureToDisplay();
329 }
330
331 void LayerRendererChromium::updateLayers(LayerList& renderSurfaceLayerList)
332 {
333     TRACE_EVENT("LayerRendererChromium::updateLayers", this, 0);
334     CCLayerImpl* rootDrawLayer = m_rootLayer->ccLayerImpl();
335
336     if (!rootDrawLayer->renderSurface())
337         rootDrawLayer->createRenderSurface();
338     ASSERT(rootDrawLayer->renderSurface());
339
340     rootDrawLayer->renderSurface()->m_contentRect = IntRect(IntPoint(0, 0), m_viewportVisibleRect.size());
341
342     IntRect rootScissorRect(m_viewportVisibleRect);
343     // The scissorRect should not include the scroll offset.
344     rootScissorRect.move(-m_viewportScrollPosition.x(), -m_viewportScrollPosition.y());
345     rootDrawLayer->setScissorRect(rootScissorRect);
346
347     m_defaultRenderSurface = rootDrawLayer->renderSurface();
348
349     renderSurfaceLayerList.append(rootDrawLayer);
350
351     TransformationMatrix identityMatrix;
352     m_defaultRenderSurface->m_layerList.clear();
353     // Unfortunately, updatePropertiesAndRenderSurfaces() currently both updates the layers and updates the draw state
354     // (transforms, etc). It'd be nicer if operations on the presentation layers happened later, but the draw
355     // transforms are needed by large layers to determine visibility. Tiling will fix this by eliminating the
356     // concept of a large content layer.
357     updatePropertiesAndRenderSurfaces(rootDrawLayer, identityMatrix, renderSurfaceLayerList, m_defaultRenderSurface->m_layerList);
358
359 #ifndef NDEBUG
360     s_inPaintLayerContents = true;
361 #endif
362     paintLayerContents(renderSurfaceLayerList);
363 #ifndef NDEBUG
364     s_inPaintLayerContents = false;
365 #endif
366     // Update compositor resources for root layer.
367     {
368         TRACE_EVENT("LayerRendererChromium::updateLayer::updateRoot", this, 0);
369         m_rootLayerContentTiler->updateRect(m_rootLayerTextureUpdater.get());
370     }
371
372     updateCompositorResources(renderSurfaceLayerList);
373 }
374
375 static IntRect calculateVisibleRect(const IntRect& targetSurfaceRect, const IntRect& layerBoundRect, const TransformationMatrix& transform)
376 {
377     // Is this layer fully contained within the target surface?
378     IntRect layerInSurfaceSpace = transform.mapRect(layerBoundRect);
379     if (targetSurfaceRect.contains(layerInSurfaceSpace))
380         return layerBoundRect;
381
382     // If the layer doesn't fill up the entire surface, then find the part of
383     // the surface rect where the layer could be visible. This avoids trying to
384     // project surface rect points that are behind the projection point.
385     IntRect minimalSurfaceRect = targetSurfaceRect;
386     minimalSurfaceRect.intersect(layerInSurfaceSpace);
387
388     // Project the corners of the target surface rect into the layer space.
389     // This bounding rectangle may be larger than it needs to be (being
390     // axis-aligned), but is a reasonable filter on the space to consider.
391     // Non-invertible transforms will create an empty rect here.
392     const TransformationMatrix surfaceToLayer = transform.inverse();
393     IntRect layerRect = surfaceToLayer.projectQuad(FloatQuad(FloatRect(minimalSurfaceRect))).enclosingBoundingBox();
394     layerRect.intersect(layerBoundRect);
395     return layerRect;
396 }
397
398 static IntRect calculateVisibleLayerRect(const IntRect& targetSurfaceRect, const IntSize& bounds, const IntSize& contentBounds, const TransformationMatrix& tilingTransform)
399 {
400     if (targetSurfaceRect.isEmpty() || contentBounds.isEmpty())
401         return targetSurfaceRect;
402
403     const IntRect layerBoundRect = IntRect(IntPoint(), contentBounds);
404     TransformationMatrix transform = tilingTransform;
405
406     transform.scaleNonUniform(bounds.width() / static_cast<double>(contentBounds.width()),
407                               bounds.height() / static_cast<double>(contentBounds.height()));
408     transform.translate(-contentBounds.width() / 2.0, -contentBounds.height() / 2.0);
409
410     return calculateVisibleRect(targetSurfaceRect, layerBoundRect, transform);
411 }
412
413 static void paintContentsIfDirty(LayerChromium* layer, const IntRect& visibleLayerRect)
414 {
415     if (layer->drawsContent()) {
416         layer->setVisibleLayerRect(visibleLayerRect);
417         layer->paintContentsIfDirty();
418     }
419 }
420
421 void LayerRendererChromium::paintLayerContents(const LayerList& renderSurfaceLayerList)
422 {
423     for (int surfaceIndex = renderSurfaceLayerList.size() - 1; surfaceIndex >= 0 ; --surfaceIndex) {
424         CCLayerImpl* renderSurfaceLayer = renderSurfaceLayerList[surfaceIndex].get();
425         RenderSurfaceChromium* renderSurface = renderSurfaceLayer->renderSurface();
426         ASSERT(renderSurface);
427
428         // Make sure any renderSurfaceLayer is associated with this layerRenderer.
429         // This is a defensive assignment in case the owner of this layer hasn't
430         // set the layerRenderer on this layer already.
431         renderSurfaceLayer->setLayerRenderer(this);
432
433         // Render surfaces whose drawable area has zero width or height
434         // will have no layers associated with them and should be skipped.
435         if (!renderSurface->m_layerList.size())
436             continue;
437
438         if (!renderSurface->m_drawOpacity)
439             continue;
440
441         LayerList& layerList = renderSurface->m_layerList;
442         ASSERT(layerList.size());
443         for (unsigned layerIndex = 0; layerIndex < layerList.size(); ++layerIndex) {
444             CCLayerImpl* ccLayerImpl = layerList[layerIndex].get();
445
446             // Layers that start a new render surface will be painted when the render
447             // surface's list is processed.
448             if (ccLayerImpl->renderSurface() && ccLayerImpl->renderSurface() != renderSurface)
449                 continue;
450
451             LayerChromium* layer = ccLayerImpl->owner();
452
453             layer->setLayerRenderer(this);
454
455             if (!layer->opacity())
456                 continue;
457
458             if (layer->maskLayer())
459                 layer->maskLayer()->setLayerRenderer(this);
460             if (layer->replicaLayer()) {
461                 layer->replicaLayer()->setLayerRenderer(this);
462                 if (layer->replicaLayer()->maskLayer())
463                     layer->replicaLayer()->maskLayer()->setLayerRenderer(this);
464             }
465
466             if (layer->bounds().isEmpty())
467                 continue;
468
469             IntRect targetSurfaceRect = ccLayerImpl->targetRenderSurface() ? ccLayerImpl->targetRenderSurface()->contentRect() : m_defaultRenderSurface->contentRect();
470             if (layer->ccLayerImpl()->usesLayerScissor())
471                 targetSurfaceRect.intersect(layer->ccLayerImpl()->scissorRect());
472             IntRect visibleLayerRect = calculateVisibleLayerRect(targetSurfaceRect, layer->bounds(), layer->contentBounds(), ccLayerImpl->drawTransform());
473
474             paintContentsIfDirty(layer, visibleLayerRect);
475
476             if (LayerChromium* maskLayer = layer->maskLayer()) {
477                 paintContentsIfDirty(maskLayer, IntRect(IntPoint(), maskLayer->contentBounds()));
478             }
479
480             if (LayerChromium* replicaLayer = layer->replicaLayer()) {
481                 paintContentsIfDirty(replicaLayer, visibleLayerRect);
482
483                 if (LayerChromium* replicaMaskLayer = replicaLayer->maskLayer()) {
484                     paintContentsIfDirty(replicaMaskLayer, IntRect(IntPoint(), replicaMaskLayer->contentBounds()));
485                 }
486             }
487         }
488     }
489 }
490
491 void LayerRendererChromium::drawLayers(const LayerList& renderSurfaceLayerList)
492 {
493     if (m_viewportVisibleRect.isEmpty() || !m_rootLayer)
494         return;
495
496     TRACE_EVENT("LayerRendererChromium::drawLayers", this, 0);
497     CCLayerImpl* rootDrawLayer = m_rootLayer->ccLayerImpl();
498     makeContextCurrent();
499
500     // The GL viewport covers the entire visible area, including the scrollbars.
501     GLC(m_context.get(), m_context->viewport(0, 0, m_viewportVisibleRect.width(), m_viewportVisibleRect.height()));
502
503     // Bind the common vertex attributes used for drawing all the layers.
504     m_sharedGeometry->prepareForDraw();
505
506     // FIXME: These calls can be made once, when the compositor context is initialized.
507     GLC(m_context.get(), m_context->disable(GraphicsContext3D::DEPTH_TEST));
508     GLC(m_context.get(), m_context->disable(GraphicsContext3D::CULL_FACE));
509
510     // Blending disabled by default. Root layer alpha channel on Windows is incorrect when Skia uses ClearType.
511     GLC(m_context.get(), m_context->disable(GraphicsContext3D::BLEND));
512
513     useRenderSurface(m_defaultRenderSurface);
514
515     // Clear to blue to make it easier to spot unrendered regions.
516     m_context->clearColor(0, 0, 1, 1);
517     m_context->colorMask(true, true, true, true);
518     m_context->clear(GraphicsContext3D::COLOR_BUFFER_BIT);
519     // Mask out writes to alpha channel: subpixel antialiasing via Skia results in invalid
520     // zero alpha values on text glyphs. The root layer is always opaque.
521     m_context->colorMask(true, true, true, false);
522
523     drawRootLayer();
524
525     // Re-enable color writes to layers, which may be partially transparent.
526     m_context->colorMask(true, true, true, true);
527
528     GLC(m_context.get(), m_context->enable(GraphicsContext3D::BLEND));
529     GLC(m_context.get(), m_context->blendFunc(GraphicsContext3D::ONE, GraphicsContext3D::ONE_MINUS_SRC_ALPHA));
530     GLC(m_context.get(), m_context->enable(GraphicsContext3D::SCISSOR_TEST));
531
532     // Update the contents of the render surfaces. We traverse the array from
533     // back to front to guarantee that nested render surfaces get rendered in the
534     // correct order.
535     for (int surfaceIndex = renderSurfaceLayerList.size() - 1; surfaceIndex >= 0 ; --surfaceIndex) {
536         CCLayerImpl* renderSurfaceLayer = renderSurfaceLayerList[surfaceIndex].get();
537         RenderSurfaceChromium* renderSurface = renderSurfaceLayer->renderSurface();
538         ASSERT(renderSurface);
539
540         renderSurface->m_skipsDraw = true;
541
542         // Render surfaces whose drawable area has zero width or height
543         // will have no layers associated with them and should be skipped.
544         if (!renderSurface->m_layerList.size())
545             continue;
546
547         // Skip completely transparent render surfaces.
548         if (!renderSurface->m_drawOpacity)
549             continue;
550
551         if (useRenderSurface(renderSurface)) {
552             renderSurface->m_skipsDraw = false;
553
554             if (renderSurfaceLayer != rootDrawLayer) {
555                 GLC(m_context.get(), m_context->disable(GraphicsContext3D::SCISSOR_TEST));
556                 GLC(m_context.get(), m_context->clearColor(0, 0, 0, 0));
557                 GLC(m_context.get(), m_context->clear(GraphicsContext3D::COLOR_BUFFER_BIT));
558                 GLC(m_context.get(), m_context->enable(GraphicsContext3D::SCISSOR_TEST));
559             }
560
561             LayerList& layerList = renderSurface->m_layerList;
562             for (unsigned layerIndex = 0; layerIndex < layerList.size(); ++layerIndex)
563                 drawLayer(layerList[layerIndex].get(), renderSurface);
564         }
565     }
566
567     if (m_headsUpDisplay->enabled()) {
568         GLC(m_context.get(), m_context->enable(GraphicsContext3D::BLEND));
569         GLC(m_context.get(), m_context->blendFunc(GraphicsContext3D::ONE, GraphicsContext3D::ONE_MINUS_SRC_ALPHA));
570         GLC(m_context.get(), m_context->disable(GraphicsContext3D::SCISSOR_TEST));
571         useRenderSurface(m_defaultRenderSurface);
572         m_headsUpDisplay->draw();
573     }
574
575     GLC(m_context.get(), m_context->disable(GraphicsContext3D::SCISSOR_TEST));
576     GLC(m_context.get(), m_context->disable(GraphicsContext3D::BLEND));
577 }
578
579 void LayerRendererChromium::finish()
580 {
581     TRACE_EVENT("LayerRendererChromium::finish", this, 0);
582     m_context->finish();
583 }
584
585 void LayerRendererChromium::present()
586 {
587     TRACE_EVENT("LayerRendererChromium::present", this, 0);
588     // We're done! Time to swapbuffers!
589
590     // Note that currently this has the same effect as swapBuffers; we should
591     // consider exposing a different entry point on GraphicsContext3D.
592     m_context->prepareTexture();
593
594     m_headsUpDisplay->onPresent();
595 }
596
597 void LayerRendererChromium::setRootLayer(PassRefPtr<LayerChromium> layer)
598 {
599     m_rootLayer = layer;
600     if (m_rootLayer)
601         m_rootLayer->setLayerRenderer(this);
602     m_rootLayerContentTiler->invalidateEntireLayer();
603 }
604
605 void LayerRendererChromium::setLayerRendererRecursive(LayerChromium* layer)
606 {
607     const Vector<RefPtr<LayerChromium> >& children = layer->children();
608     for (size_t i = 0; i < children.size(); ++i)
609         setLayerRendererRecursive(children[i].get());
610
611     if (layer->maskLayer())
612         setLayerRendererRecursive(layer->maskLayer());
613     if (layer->replicaLayer())
614         setLayerRendererRecursive(layer->replicaLayer());
615
616     layer->setLayerRenderer(this);
617 }
618
619 void LayerRendererChromium::transferRootLayer(LayerRendererChromium* other)
620 {
621     other->setLayerRendererRecursive(m_rootLayer.get());
622     other->m_rootLayer = m_rootLayer.release();
623 }
624
625 void LayerRendererChromium::getFramebufferPixels(void *pixels, const IntRect& rect)
626 {
627     ASSERT(rect.maxX() <= m_viewportVisibleRect.width() && rect.maxY() <= m_viewportVisibleRect.height());
628
629     if (!pixels)
630         return;
631
632     makeContextCurrent();
633
634     GLC(m_context.get(), m_context->readPixels(rect.x(), rect.y(), rect.width(), rect.height(),
635                                          GraphicsContext3D::RGBA, GraphicsContext3D::UNSIGNED_BYTE, pixels));
636 }
637
638 // FIXME: This method should eventually be replaced by a proper texture manager.
639 unsigned LayerRendererChromium::createLayerTexture()
640 {
641     unsigned textureId = 0;
642     GLC(m_context.get(), textureId = m_context->createTexture());
643     GLC(m_context.get(), m_context->bindTexture(GraphicsContext3D::TEXTURE_2D, textureId));
644     // Do basic linear filtering on resize.
645     GLC(m_context.get(), m_context->texParameteri(GraphicsContext3D::TEXTURE_2D, GraphicsContext3D::TEXTURE_MIN_FILTER, GraphicsContext3D::LINEAR));
646     GLC(m_context.get(), m_context->texParameteri(GraphicsContext3D::TEXTURE_2D, GraphicsContext3D::TEXTURE_MAG_FILTER, GraphicsContext3D::LINEAR));
647     // NPOT textures in GL ES only work when the wrap mode is set to GraphicsContext3D::CLAMP_TO_EDGE.
648     GLC(m_context.get(), m_context->texParameteri(GraphicsContext3D::TEXTURE_2D, GraphicsContext3D::TEXTURE_WRAP_S, GraphicsContext3D::CLAMP_TO_EDGE));
649     GLC(m_context.get(), m_context->texParameteri(GraphicsContext3D::TEXTURE_2D, GraphicsContext3D::TEXTURE_WRAP_T, GraphicsContext3D::CLAMP_TO_EDGE));
650     return textureId;
651 }
652
653 void LayerRendererChromium::deleteLayerTexture(unsigned textureId)
654 {
655     if (!textureId)
656         return;
657
658     GLC(m_context.get(), m_context->deleteTexture(textureId));
659 }
660
661 // Returns true if any part of the layer falls within the visibleRect
662 bool LayerRendererChromium::isLayerVisible(LayerChromium* layer, const TransformationMatrix& matrix, const IntRect& visibleRect)
663 {
664     // Form the matrix used by the shader to map the corners of the layer's
665     // bounds into clip space.
666     TransformationMatrix renderMatrix = matrix;
667     renderMatrix.scale3d(layer->bounds().width(), layer->bounds().height(), 1);
668     renderMatrix = m_projectionMatrix * renderMatrix;
669
670     FloatRect layerRect(-0.5, -0.5, 1, 1);
671     FloatRect mappedRect = renderMatrix.mapRect(layerRect);
672
673     // The layer is visible if it intersects any part of a rectangle whose origin
674     // is at (-1, -1) and size is 2x2.
675     return mappedRect.intersects(FloatRect(-1, -1, 2, 2));
676 }
677
678 // Recursively walks the layer tree starting at the given node and computes all the
679 // necessary transformations, scissor rectangles, render surfaces, etc.
680 void LayerRendererChromium::updatePropertiesAndRenderSurfaces(CCLayerImpl* layer, const TransformationMatrix& parentMatrix, LayerList& renderSurfaceLayerList, LayerList& layerList)
681 {
682     // Compute the new matrix transformation that will be applied to this layer and
683     // all its children. It's important to remember that the layer's position
684     // is the position of the layer's anchor point. Also, the coordinate system used
685     // assumes that the origin is at the lower left even though the coordinates the browser
686     // gives us for the layers are for the upper left corner. The Y flip happens via
687     // the orthographic projection applied at render time.
688     // The transformation chain for the layer is (using the Matrix x Vector order):
689     // M = M[p] * Tr[l] * M[l] * Tr[c]
690     // Where M[p] is the parent matrix passed down to the function
691     //       Tr[l] is the translation matrix locating the layer's anchor point
692     //       Tr[c] is the translation offset between the anchor point and the center of the layer
693     //       M[l] is the layer's matrix (applied at the anchor point)
694     // This transform creates a coordinate system whose origin is the center of the layer.
695     // Note that the final matrix used by the shader for the layer is P * M * S . This final product
696     // is computed in drawTexturedQuad().
697     // Where: P is the projection matrix
698     //        M is the layer's matrix computed above
699     //        S is the scale adjustment (to scale up to the layer size)
700     IntSize bounds = layer->bounds();
701     FloatPoint anchorPoint = layer->anchorPoint();
702     FloatPoint position = layer->position();
703
704     // Offset between anchor point and the center of the quad.
705     float centerOffsetX = (0.5 - anchorPoint.x()) * bounds.width();
706     float centerOffsetY = (0.5 - anchorPoint.y()) * bounds.height();
707
708     TransformationMatrix layerLocalTransform;
709     // LT = Tr[l]
710     layerLocalTransform.translate3d(position.x(), position.y(), layer->anchorPointZ());
711     // LT = Tr[l] * M[l]
712     layerLocalTransform.multiply(layer->transform());
713     // LT = Tr[l] * M[l] * Tr[c]
714     layerLocalTransform.translate3d(centerOffsetX, centerOffsetY, -layer->anchorPointZ());
715
716     TransformationMatrix combinedTransform = parentMatrix;
717     combinedTransform = combinedTransform.multiply(layerLocalTransform);
718
719     FloatRect layerRect(-0.5 * layer->bounds().width(), -0.5 * layer->bounds().height(), layer->bounds().width(), layer->bounds().height());
720     IntRect transformedLayerRect;
721
722     // FIXME: This seems like the wrong place to set this
723     layer->setUsesLayerScissor(false);
724
725     // The layer and its descendants render on a new RenderSurface if any of
726     // these conditions hold:
727     // 1. The layer clips its descendants and its transform is not a simple translation.
728     // 2. If the layer has opacity != 1 and does not have a preserves-3d transform style.
729     // 3. The layer uses a mask
730     // 4. The layer has a replica (used for reflections)
731     // 5. The layer doesn't preserve-3d but is the child of a layer which does.
732     // If a layer preserves-3d then we don't create a RenderSurface for it to avoid flattening
733     // out its children. The opacity value of the children layers is multiplied by the opacity
734     // of their parent.
735     bool useSurfaceForClipping = layer->masksToBounds() && !isScaleOrTranslation(combinedTransform);
736     bool useSurfaceForOpacity = layer->opacity() != 1 && !layer->preserves3D();
737     bool useSurfaceForMasking = layer->maskLayer();
738     bool useSurfaceForReflection = layer->replicaLayer();
739     bool useSurfaceForFlatDescendants = layer->parent() && layer->parent()->preserves3D() && !layer->preserves3D() && layer->descendantsDrawsContent();
740     if (useSurfaceForMasking || useSurfaceForReflection || useSurfaceForFlatDescendants || ((useSurfaceForClipping || useSurfaceForOpacity) && layer->descendantsDrawsContent())) {
741         RenderSurfaceChromium* renderSurface = layer->renderSurface();
742         if (!renderSurface)
743             renderSurface = layer->createRenderSurface();
744
745         // The origin of the new surface is the upper left corner of the layer.
746         TransformationMatrix drawTransform;
747         drawTransform.translate3d(0.5 * bounds.width(), 0.5 * bounds.height(), 0);
748         layer->setDrawTransform(drawTransform);
749
750         transformedLayerRect = IntRect(0, 0, bounds.width(), bounds.height());
751
752         // Layer's opacity will be applied when drawing the render surface.
753         renderSurface->m_drawOpacity = layer->opacity();
754         if (layer->parent() && layer->parent()->preserves3D())
755             renderSurface->m_drawOpacity *= layer->parent()->drawOpacity();
756         layer->setDrawOpacity(1);
757
758         TransformationMatrix layerOriginTransform = combinedTransform;
759         layerOriginTransform.translate3d(-0.5 * bounds.width(), -0.5 * bounds.height(), 0);
760         renderSurface->m_originTransform = layerOriginTransform;
761
762         // The render surface scissor rect is the scissor rect that needs to
763         // be applied before drawing the render surface onto its containing
764         // surface and is therefore expressed in the parent's coordinate system.
765         renderSurface->m_scissorRect = layer->parent() ? layer->parent()->scissorRect() : layer->scissorRect();
766
767         renderSurface->m_layerList.clear();
768
769         if (layer->maskLayer()) {
770             renderSurface->m_maskLayer = layer->maskLayer();
771             layer->maskLayer()->setTargetRenderSurface(renderSurface);
772         } else
773             renderSurface->m_maskLayer = 0;
774
775         if (layer->replicaLayer() && layer->replicaLayer()->maskLayer())
776             layer->replicaLayer()->maskLayer()->setTargetRenderSurface(renderSurface);
777
778         renderSurfaceLayerList.append(layer);
779     } else {
780         // DT = M[p] * LT
781         layer->setDrawTransform(combinedTransform);
782         transformedLayerRect = enclosingIntRect(layer->drawTransform().mapRect(layerRect));
783
784         layer->setDrawOpacity(layer->opacity());
785
786         if (layer->parent()) {
787             if (layer->parent()->preserves3D())
788                layer->setDrawOpacity(layer->drawOpacity() * layer->parent()->drawOpacity());
789
790             // Layers inherit the scissor rect from their parent.
791             layer->setScissorRect(layer->parent()->scissorRect());
792             if (layer->parent()->usesLayerScissor())
793                 layer->setUsesLayerScissor(true);
794
795             layer->setTargetRenderSurface(layer->parent()->targetRenderSurface());
796         }
797
798         if (layer != m_rootCCLayerImpl.get())
799             layer->clearRenderSurface();
800
801         if (layer->masksToBounds()) {
802             IntRect scissor = transformedLayerRect;
803             if (!layer->scissorRect().isEmpty())
804                 scissor.intersect(layer->scissorRect());
805             layer->setScissorRect(scissor);
806             layer->setUsesLayerScissor(true);
807         }
808     }
809
810     if (layer->renderSurface())
811         layer->setTargetRenderSurface(layer->renderSurface());
812     else {
813         ASSERT(layer->parent());
814         layer->setTargetRenderSurface(layer->parent()->targetRenderSurface());
815     }
816
817     // drawableContentRect() is always stored in the coordinate system of the
818     // RenderSurface the layer draws into.
819     if (layer->drawsContent()) {
820         IntRect drawableContentRect = transformedLayerRect;
821         if (layer->usesLayerScissor())
822             drawableContentRect.intersect(layer->scissorRect());
823         layer->setDrawableContentRect(drawableContentRect);
824     } else
825         layer->setDrawableContentRect(IntRect());
826
827     TransformationMatrix sublayerMatrix = layer->drawTransform();
828
829     // Flatten to 2D if the layer doesn't preserve 3D.
830     if (!layer->preserves3D()) {
831         sublayerMatrix.setM13(0);
832         sublayerMatrix.setM23(0);
833         sublayerMatrix.setM31(0);
834         sublayerMatrix.setM32(0);
835         sublayerMatrix.setM33(1);
836         sublayerMatrix.setM34(0);
837         sublayerMatrix.setM43(0);
838     }
839
840     // Apply the sublayer transform at the center of the layer.
841     sublayerMatrix.multiply(layer->sublayerTransform());
842
843     // The origin of the children is the top left corner of the layer, not the
844     // center. The matrix passed down to the children is therefore:
845     // M[s] = M * Tr[-center]
846     sublayerMatrix.translate3d(-bounds.width() * 0.5, -bounds.height() * 0.5, 0);
847
848     LayerList& descendants = (layer->renderSurface() ? layer->renderSurface()->m_layerList : layerList);
849     descendants.append(layer);
850
851     unsigned thisLayerIndex = descendants.size() - 1;
852
853     for (size_t i = 0; i < layer->children().size(); ++i) {
854         CCLayerImpl* child = layer->children()[i].get();
855         updatePropertiesAndRenderSurfaces(child, sublayerMatrix, renderSurfaceLayerList, descendants);
856
857         if (child->renderSurface()) {
858             RenderSurfaceChromium* childRenderSurface = child->renderSurface();
859             IntRect drawableContentRect = layer->drawableContentRect();
860             drawableContentRect.unite(enclosingIntRect(childRenderSurface->drawableContentRect()));
861             layer->setDrawableContentRect(drawableContentRect);
862             descendants.append(child);
863         } else {
864             IntRect drawableContentRect = layer->drawableContentRect();
865             drawableContentRect.unite(child->drawableContentRect());
866             layer->setDrawableContentRect(drawableContentRect);
867         }
868     }
869
870     if (layer->masksToBounds() || useSurfaceForMasking) {
871         IntRect drawableContentRect = layer->drawableContentRect();
872         drawableContentRect.intersect(transformedLayerRect);
873         layer->setDrawableContentRect(drawableContentRect);
874     }
875
876     if (layer->renderSurface() && layer != m_rootCCLayerImpl.get()) {
877         RenderSurfaceChromium* renderSurface = layer->renderSurface();
878         renderSurface->m_contentRect = layer->drawableContentRect();
879         FloatPoint surfaceCenter = renderSurface->contentRectCenter();
880
881         // Restrict the RenderSurface size to the portion that's visible.
882         FloatSize centerOffsetDueToClipping;
883
884         // Don't clip if the layer is reflected as the reflection shouldn't be
885         // clipped.
886         if (!layer->replicaLayer()) {
887             if (!renderSurface->m_scissorRect.isEmpty() && !renderSurface->m_contentRect.isEmpty()) {
888                 IntRect surfaceScissorRect = calculateVisibleRect(renderSurface->m_scissorRect, renderSurface->m_contentRect, renderSurface->m_originTransform);
889                 renderSurface->m_contentRect.intersect(surfaceScissorRect);
890             }
891             FloatPoint clippedSurfaceCenter = renderSurface->contentRectCenter();
892             centerOffsetDueToClipping = clippedSurfaceCenter - surfaceCenter;
893         }
894
895         // The RenderSurface backing texture cannot exceed the maximum supported
896         // texture size.
897         renderSurface->m_contentRect.setWidth(std::min(renderSurface->m_contentRect.width(), m_maxTextureSize));
898         renderSurface->m_contentRect.setHeight(std::min(renderSurface->m_contentRect.height(), m_maxTextureSize));
899
900         if (renderSurface->m_contentRect.isEmpty())
901             renderSurface->m_layerList.clear();
902
903         // Since the layer starts a new render surface we need to adjust its
904         // scissor rect to be expressed in the new surface's coordinate system.
905         layer->setScissorRect(layer->drawableContentRect());
906
907         // Adjust the origin of the transform to be the center of the render surface.
908         renderSurface->m_drawTransform = renderSurface->m_originTransform;
909         renderSurface->m_drawTransform.translate3d(surfaceCenter.x() + centerOffsetDueToClipping.width(), surfaceCenter.y() + centerOffsetDueToClipping.height(), 0);
910
911         // Compute the transformation matrix used to draw the replica of the render
912         // surface.
913         if (layer->replicaLayer()) {
914             renderSurface->m_replicaDrawTransform = renderSurface->m_originTransform;
915             renderSurface->m_replicaDrawTransform.translate3d(layer->replicaLayer()->position().x(), layer->replicaLayer()->position().y(), 0);
916             renderSurface->m_replicaDrawTransform.multiply(layer->replicaLayer()->transform());
917             renderSurface->m_replicaDrawTransform.translate3d(surfaceCenter.x() - anchorPoint.x() * bounds.width(), surfaceCenter.y() - anchorPoint.y() * bounds.height(), 0);
918         }
919     }
920
921     // If preserves-3d then sort all the descendants in 3D so that they can be 
922     // drawn from back to front. If the preserves-3d property is also set on the parent then
923     // skip the sorting as the parent will sort all the descendants anyway.
924     if (layer->preserves3D() && (!layer->parent() || !layer->parent()->preserves3D()))
925         m_layerSorter.sort(&descendants.at(thisLayerIndex), descendants.end());
926 }
927
928 void LayerRendererChromium::updateCompositorResources(const LayerList& renderSurfaceLayerList)
929 {
930     for (int surfaceIndex = renderSurfaceLayerList.size() - 1; surfaceIndex >= 0 ; --surfaceIndex) {
931         CCLayerImpl* renderSurfaceLayer = renderSurfaceLayerList[surfaceIndex].get();
932         RenderSurfaceChromium* renderSurface = renderSurfaceLayer->renderSurface();
933         ASSERT(renderSurface);
934
935         if (!renderSurface->m_layerList.size() || !renderSurface->m_drawOpacity)
936             continue;
937
938         LayerList& layerList = renderSurface->m_layerList;
939         ASSERT(layerList.size());
940         for (unsigned layerIndex = 0; layerIndex < layerList.size(); ++layerIndex) {
941             CCLayerImpl* ccLayerImpl = layerList[layerIndex].get();
942             if (ccLayerImpl->renderSurface() && ccLayerImpl->renderSurface() != renderSurface)
943                 continue;
944
945             updateCompositorResources(ccLayerImpl);
946         }
947     }
948 }
949
950 void LayerRendererChromium::updateCompositorResources(CCLayerImpl* ccLayerImpl)
951 {
952     LayerChromium* layer = ccLayerImpl->owner();
953
954     if (layer->bounds().isEmpty())
955         return;
956
957     if (!layer->opacity())
958         return;
959
960     if (layer->maskLayer())
961         updateCompositorResources(ccLayerImpl->maskLayer());
962     if (layer->replicaLayer())
963         updateCompositorResources(ccLayerImpl->replicaLayer());
964
965     if (layer->drawsContent())
966         layer->updateCompositorResources();
967
968     layer->pushPropertiesTo(ccLayerImpl);
969 }
970
971 void LayerRendererChromium::setCompositeOffscreen(bool compositeOffscreen)
972 {
973     if (m_compositeOffscreen == compositeOffscreen)
974        return;
975
976     m_compositeOffscreen = compositeOffscreen;
977
978     if (!m_compositeOffscreen && m_rootLayer)
979         m_rootLayer->ccLayerImpl()->clearRenderSurface();
980 }
981
982 LayerTexture* LayerRendererChromium::getOffscreenLayerTexture()
983 {
984     return m_compositeOffscreen ? m_rootLayer->ccLayerImpl()->renderSurface()->m_contentsTexture.get() : 0;
985 }
986
987 void LayerRendererChromium::copyOffscreenTextureToDisplay()
988 {
989     if (m_compositeOffscreen) {
990         makeContextCurrent();
991
992         useRenderSurface(0);
993         m_defaultRenderSurface->m_drawTransform.makeIdentity();
994         m_defaultRenderSurface->m_drawTransform.translate3d(0.5 * m_defaultRenderSurface->m_contentRect.width(),
995                                                             0.5 * m_defaultRenderSurface->m_contentRect.height(), 0);
996         m_defaultRenderSurface->m_drawOpacity = 1;
997         m_defaultRenderSurface->draw(m_defaultRenderSurface->m_contentRect);
998     }
999 }
1000
1001 bool LayerRendererChromium::useRenderSurface(RenderSurfaceChromium* renderSurface)
1002 {
1003     if (m_currentRenderSurface == renderSurface)
1004         return true;
1005
1006     m_currentRenderSurface = renderSurface;
1007
1008     if ((renderSurface == m_defaultRenderSurface && !m_compositeOffscreen) || (!renderSurface && m_compositeOffscreen)) {
1009         GLC(m_context.get(), m_context->bindFramebuffer(GraphicsContext3D::FRAMEBUFFER, 0));
1010         if (renderSurface)
1011             setDrawViewportRect(renderSurface->m_contentRect, true);
1012         else
1013             setDrawViewportRect(m_defaultRenderSurface->m_contentRect, true);
1014         return true;
1015     }
1016
1017     GLC(m_context.get(), m_context->bindFramebuffer(GraphicsContext3D::FRAMEBUFFER, m_offscreenFramebufferId));
1018
1019     if (!renderSurface->prepareContentsTexture())
1020         return false;
1021
1022     renderSurface->m_contentsTexture->framebufferTexture2D();
1023
1024 #if !defined ( NDEBUG )
1025     if (m_context->checkFramebufferStatus(GraphicsContext3D::FRAMEBUFFER) != GraphicsContext3D::FRAMEBUFFER_COMPLETE) {
1026         ASSERT_NOT_REACHED();
1027         return false;
1028     }
1029 #endif
1030
1031     setDrawViewportRect(renderSurface->m_contentRect, false);
1032     return true;
1033 }
1034
1035 void LayerRendererChromium::drawLayer(CCLayerImpl* layer, RenderSurfaceChromium* targetSurface)
1036 {
1037     if (layer->renderSurface() && layer->renderSurface() != targetSurface) {
1038         layer->renderSurface()->draw(layer->getDrawRect());
1039         layer->renderSurface()->releaseContentsTexture();
1040         return;
1041     }
1042
1043     if (!layer->drawsContent())
1044         return;
1045
1046     if (!layer->opacity())
1047         return;
1048
1049     if (layer->bounds().isEmpty())
1050         return;
1051
1052     IntRect targetSurfaceRect = layer->targetRenderSurface() ? layer->targetRenderSurface()->contentRect() : m_defaultRenderSurface->contentRect();
1053     if (layer->usesLayerScissor()) {
1054         IntRect scissorRect = layer->scissorRect();
1055         targetSurfaceRect.intersect(scissorRect);
1056         if (targetSurfaceRect.isEmpty())
1057             return;
1058         setScissorToRect(scissorRect);
1059     } else
1060         GLC(m_context.get(), m_context->disable(GraphicsContext3D::SCISSOR_TEST));
1061
1062
1063     // FIXME: Need to take into account the commulative render surface transforms all the way from
1064     //        the default render surface in order to determine visibility.
1065     TransformationMatrix combinedDrawMatrix = (layer->targetRenderSurface() ? layer->targetRenderSurface()->drawTransform().multiply(layer->drawTransform()) : layer->drawTransform());
1066     
1067     if (!layer->doubleSided()) {
1068         FloatRect layerRect(FloatPoint(0, 0), FloatSize(layer->bounds()));
1069         FloatQuad mappedLayer = combinedDrawMatrix.mapQuad(FloatQuad(layerRect));
1070         FloatSize horizontalDir = mappedLayer.p2() - mappedLayer.p1();
1071         FloatSize verticalDir = mappedLayer.p4() - mappedLayer.p1();
1072         FloatPoint3D xAxis(horizontalDir.width(), horizontalDir.height(), 0);
1073         FloatPoint3D yAxis(verticalDir.width(), verticalDir.height(), 0);
1074         FloatPoint3D zAxis = xAxis.cross(yAxis);
1075         if (zAxis.z() < 0)
1076             return;
1077     }
1078
1079     layer->draw();
1080
1081     // Draw the debug border if there is one.
1082     layer->drawDebugBorder();
1083 }
1084
1085 // Sets the scissor region to the given rectangle. The coordinate system for the
1086 // scissorRect has its origin at the top left corner of the current visible rect.
1087 void LayerRendererChromium::setScissorToRect(const IntRect& scissorRect)
1088 {
1089     IntRect contentRect = (m_currentRenderSurface ? m_currentRenderSurface->m_contentRect : m_defaultRenderSurface->m_contentRect);
1090
1091     GLC(m_context.get(), m_context->enable(GraphicsContext3D::SCISSOR_TEST));
1092
1093     // The scissor coordinates must be supplied in viewport space so we need to offset
1094     // by the relative position of the top left corner of the current render surface.
1095     int scissorX = scissorRect.x() - contentRect.x();
1096     // When rendering to the default render surface we're rendering upside down so the top
1097     // of the GL scissor is the bottom of our layer.
1098     // But, if rendering to offscreen texture, we reverse our sense of 'upside down'.
1099     int scissorY;
1100     if (m_currentRenderSurface == m_defaultRenderSurface && !m_compositeOffscreen)
1101         scissorY = m_currentRenderSurface->m_contentRect.height() - (scissorRect.maxY() - m_currentRenderSurface->m_contentRect.y());
1102     else
1103         scissorY = scissorRect.y() - contentRect.y();
1104     GLC(m_context.get(), m_context->scissor(scissorX, scissorY, scissorRect.width(), scissorRect.height()));
1105 }
1106
1107 bool LayerRendererChromium::makeContextCurrent()
1108 {
1109     m_context->makeContextCurrent();
1110     return true;
1111 }
1112
1113 // Checks whether a given size is within the maximum allowed texture size range.
1114 bool LayerRendererChromium::checkTextureSize(const IntSize& textureSize)
1115 {
1116     if (textureSize.width() > m_maxTextureSize || textureSize.height() > m_maxTextureSize)
1117         return false;
1118     return true;
1119 }
1120
1121 // Sets the coordinate range of content that ends being drawn onto the target render surface.
1122 // The target render surface is assumed to have an origin at 0, 0 and the width and height of
1123 // of the drawRect.
1124 void LayerRendererChromium::setDrawViewportRect(const IntRect& drawRect, bool flipY)
1125 {
1126     if (flipY)
1127         m_projectionMatrix = orthoMatrix(drawRect.x(), drawRect.maxX(), drawRect.maxY(), drawRect.y());
1128     else
1129         m_projectionMatrix = orthoMatrix(drawRect.x(), drawRect.maxX(), drawRect.y(), drawRect.maxY());
1130     GLC(m_context.get(), m_context->viewport(0, 0, drawRect.width(), drawRect.height()));
1131 }
1132
1133
1134
1135 void LayerRendererChromium::resizeOnscreenContent(const IntSize& size)
1136 {
1137     if (m_context)
1138         m_context->reshape(size.width(), size.height());
1139 }
1140
1141 bool LayerRendererChromium::initializeSharedObjects()
1142 {
1143     TRACE_EVENT("LayerRendererChromium::initializeSharedObjects", this, 0);
1144     makeContextCurrent();
1145
1146     // Get the max texture size supported by the system.
1147     m_maxTextureSize = 0;
1148     GLC(m_context.get(), m_context->getIntegerv(GraphicsContext3D::MAX_TEXTURE_SIZE, &m_maxTextureSize));
1149
1150     // Create an FBO for doing offscreen rendering.
1151     GLC(m_context.get(), m_offscreenFramebufferId = m_context->createFramebuffer());
1152
1153     // We will always need these programs to render, so create the programs eagerly so that the shader compilation can
1154     // start while we do other work. Other programs are created lazily on first access.
1155     m_sharedGeometry = adoptPtr(new GeometryBinding(m_context.get()));
1156     m_renderSurfaceProgram = adoptPtr(new RenderSurfaceChromium::Program(m_context.get()));
1157     m_tilerProgram = adoptPtr(new LayerTilerChromium::Program(m_context.get()));
1158
1159     GLC(m_context.get(), m_context->flush());
1160
1161     TextureManager::TextureMemoryLimits limits;
1162     limits.upperLimit = textureMemoryHighLimitBytes;
1163     limits.reclaimLimit = textureMemoryReclaimLimitBytes;
1164     m_textureManager = TextureManager::create(m_context.get(), limits, m_maxTextureSize);
1165     return true;
1166 }
1167
1168 const LayerChromium::BorderProgram* LayerRendererChromium::borderProgram()
1169 {
1170     if (!m_borderProgram)
1171         m_borderProgram = adoptPtr(new LayerChromium::BorderProgram(m_context.get()));
1172     if (!m_borderProgram->initialized()) {
1173         TRACE_EVENT("LayerRendererChromium::borderProgram::initialize", this, 0);
1174         m_borderProgram->initialize();
1175     }
1176     return m_borderProgram.get();
1177 }
1178
1179 const CCHeadsUpDisplay::Program* LayerRendererChromium::headsUpDisplayProgram()
1180 {
1181     if (!m_headsUpDisplayProgram)
1182         m_headsUpDisplayProgram = adoptPtr(new CCHeadsUpDisplay::Program(m_context.get()));
1183     if (!m_headsUpDisplayProgram->initialized()) {
1184         TRACE_EVENT("LayerRendererChromium::borderProgram::initialize", this, 0);
1185         m_headsUpDisplayProgram->initialize();
1186     }
1187     return m_headsUpDisplayProgram.get();
1188 }
1189
1190 const RenderSurfaceChromium::Program* LayerRendererChromium::renderSurfaceProgram()
1191 {
1192     ASSERT(m_renderSurfaceProgram);
1193     if (!m_renderSurfaceProgram->initialized()) {
1194         TRACE_EVENT("LayerRendererChromium::borderProgram::initialize", this, 0);
1195         m_renderSurfaceProgram->initialize();
1196     }
1197     return m_renderSurfaceProgram.get();
1198 }
1199
1200 const RenderSurfaceChromium::MaskProgram* LayerRendererChromium::renderSurfaceMaskProgram()
1201 {
1202     if (!m_renderSurfaceMaskProgram)
1203         m_renderSurfaceMaskProgram = adoptPtr(new RenderSurfaceChromium::MaskProgram(m_context.get()));
1204     if (!m_renderSurfaceMaskProgram->initialized()) {
1205         TRACE_EVENT("LayerRendererChromium::borderProgram::initialize", this, 0);
1206         m_renderSurfaceMaskProgram->initialize();
1207     }
1208     return m_renderSurfaceMaskProgram.get();
1209 }
1210
1211 const LayerTilerChromium::Program* LayerRendererChromium::tilerProgram()
1212 {
1213     ASSERT(m_tilerProgram);
1214     if (!m_tilerProgram->initialized()) {
1215         TRACE_EVENT("LayerRendererChromium::tilerProgram::initialize", this, 0);
1216         m_tilerProgram->initialize();
1217     }
1218     return m_tilerProgram.get();
1219 }
1220
1221 const LayerTilerChromium::ProgramSwizzle* LayerRendererChromium::tilerProgramSwizzle()
1222 {
1223     if (!m_tilerProgramSwizzle)
1224         m_tilerProgramSwizzle = adoptPtr(new LayerTilerChromium::ProgramSwizzle(m_context.get()));
1225     if (!m_tilerProgramSwizzle->initialized()) {
1226         TRACE_EVENT("LayerRendererChromium::tilerProgramSwizzle::initialize", this, 0);
1227         m_tilerProgramSwizzle->initialize();
1228     }
1229     return m_tilerProgramSwizzle.get();
1230 }
1231
1232 const CCCanvasLayerImpl::Program* LayerRendererChromium::canvasLayerProgram()
1233 {
1234     if (!m_canvasLayerProgram)
1235         m_canvasLayerProgram = adoptPtr(new CCCanvasLayerImpl::Program(m_context.get()));
1236     if (!m_canvasLayerProgram->initialized()) {
1237         TRACE_EVENT("LayerRendererChromium::borderProgram::initialize", this, 0);
1238         m_canvasLayerProgram->initialize();
1239     }
1240     return m_canvasLayerProgram.get();
1241 }
1242
1243 const CCPluginLayerImpl::Program* LayerRendererChromium::pluginLayerProgram()
1244 {
1245     if (!m_pluginLayerProgram)
1246         m_pluginLayerProgram = adoptPtr(new CCPluginLayerImpl::Program(m_context.get()));
1247     if (!m_pluginLayerProgram->initialized()) {
1248         TRACE_EVENT("LayerRendererChromium::borderProgram::initialize", this, 0);
1249         m_pluginLayerProgram->initialize();
1250     }
1251     return m_pluginLayerProgram.get();
1252 }
1253
1254 const CCVideoLayerImpl::RGBAProgram* LayerRendererChromium::videoLayerRGBAProgram()
1255 {
1256     if (!m_videoLayerRGBAProgram)
1257         m_videoLayerRGBAProgram = adoptPtr(new CCVideoLayerImpl::RGBAProgram(m_context.get()));
1258     if (!m_videoLayerRGBAProgram->initialized()) {
1259         TRACE_EVENT("LayerRendererChromium::borderProgram::initialize", this, 0);
1260         m_videoLayerRGBAProgram->initialize();
1261     }
1262     return m_videoLayerRGBAProgram.get();
1263 }
1264
1265 const CCVideoLayerImpl::YUVProgram* LayerRendererChromium::videoLayerYUVProgram()
1266 {
1267     if (!m_videoLayerYUVProgram)
1268         m_videoLayerYUVProgram = adoptPtr(new CCVideoLayerImpl::YUVProgram(m_context.get()));
1269     if (!m_videoLayerYUVProgram->initialized()) {
1270         TRACE_EVENT("LayerRendererChromium::borderProgram::initialize", this, 0);
1271         m_videoLayerYUVProgram->initialize();
1272     }
1273     return m_videoLayerYUVProgram.get();
1274 }
1275
1276
1277 void LayerRendererChromium::cleanupSharedObjects()
1278 {
1279     makeContextCurrent();
1280
1281     m_sharedGeometry.clear();
1282     m_borderProgram.clear();
1283     m_canvasLayerProgram.clear();
1284     m_headsUpDisplayProgram.clear();
1285     m_videoLayerRGBAProgram.clear();
1286     m_videoLayerYUVProgram.clear();
1287     m_pluginLayerProgram.clear();
1288     m_renderSurfaceProgram.clear();
1289     m_renderSurfaceMaskProgram.clear();
1290     m_tilerProgram.clear();
1291     m_tilerProgramSwizzle.clear();
1292     if (m_offscreenFramebufferId)
1293         GLC(m_context.get(), m_context->deleteFramebuffer(m_offscreenFramebufferId));
1294
1295     // Clear tilers before the texture manager, as they have references to textures.
1296     m_rootLayerContentTiler.clear();
1297
1298     m_textureManager.clear();
1299 }
1300
1301 String LayerRendererChromium::layerTreeAsText() const
1302 {
1303     TextStream ts;
1304     if (m_rootLayer.get()) {
1305         ts << m_rootLayer->layerTreeAsText();
1306         ts << "RenderSurfaces:\n";
1307         dumpRenderSurfaces(ts, 1, m_rootLayer.get());
1308     }
1309     return ts.release();
1310 }
1311
1312 void LayerRendererChromium::addChildContext(GraphicsContext3D* ctx)
1313 {
1314     if (!ctx->getExtensions()->supports("GL_CHROMIUM_latch"))
1315         return;
1316
1317     // This is a ref-counting map, because some contexts are shared by multiple
1318     // layers (specifically, Canvas2DLayerChromium).
1319
1320     // Insert the ctx with a count of 1, or return the existing iterator.
1321     std::pair<ChildContextMap::iterator, bool> insert_result = m_childContexts.add(ctx, 1);
1322     if (!insert_result.second) {
1323         // Already present in map, so increment.
1324         ++insert_result.first->second;
1325     } else {
1326 // FIXME(jbates): when compositor is multithreaded and copyTexImage2D bug is fixed,
1327 // uncomment this block:
1328 //      // This is a new child context - set the parentToChild latch so that it
1329 //      // can continue past its first wait latch.
1330 //      Extensions3DChromium* ext = static_cast<Extensions3DChromium*>(ctx->getExtensions());
1331 //      GC3Duint latchId;
1332 //      ext->getParentToChildLatchCHROMIUM(&latchId);
1333 //      ext->setLatchCHROMIUM(0, latchId);
1334     }
1335 }
1336
1337 void LayerRendererChromium::removeChildContext(GraphicsContext3D* ctx)
1338 {
1339     if (!ctx->getExtensions()->supports("GL_CHROMIUM_latch"))
1340         return;
1341
1342     ChildContextMap::iterator i = m_childContexts.find(ctx);
1343     if (i != m_childContexts.end()) {
1344         if (--i->second <= 0) {
1345             // Count reached zero, so remove from map.
1346             m_childContexts.remove(i);
1347         }
1348     } else {
1349         // error
1350         ASSERT(0 && "m_childContexts map has mismatched add/remove calls");
1351     }
1352 }
1353
1354 bool LayerRendererChromium::isCompositorContextLost()
1355 {
1356     return (m_context.get()->getExtensions()->getGraphicsResetStatusARB() != GraphicsContext3D::NO_ERROR);
1357 }
1358
1359 void LayerRendererChromium::dumpRenderSurfaces(TextStream& ts, int indent, LayerChromium* layer) const
1360 {
1361     if (layer->ccLayerImpl()->renderSurface())
1362         layer->ccLayerImpl()->renderSurface()->dumpSurface(ts, indent);
1363
1364     for (size_t i = 0; i < layer->children().size(); ++i)
1365         dumpRenderSurfaces(ts, indent, layer->children()[i].get());
1366 }
1367
1368 class LayerRendererChromiumImpl : public CCLayerTreeHostImpl {
1369 public:
1370     static PassOwnPtr<LayerRendererChromiumImpl> create(CCLayerTreeHostImplClient* client, LayerRendererChromium* layerRenderer)
1371     {
1372         return adoptPtr(new LayerRendererChromiumImpl(client, layerRenderer));
1373     }
1374
1375     virtual void drawLayersAndPresent()
1376     {
1377         CCCompletionEvent completion;
1378         bool contextLost;
1379         CCMainThread::postTask(createMainThreadTask(this, &LayerRendererChromiumImpl::drawLayersOnMainThread, AllowCrossThreadAccess(&completion), AllowCrossThreadAccess(&contextLost)));
1380         completion.wait();
1381
1382         // FIXME: Send the "UpdateRect" message up to the RenderWidget [or moveplugin equivalents...]
1383
1384         // FIXME: handle context lost
1385         if (contextLost)
1386             FATAL("LayerRendererChromiumImpl does not handle context lost yet.");
1387     }
1388
1389 private:
1390     LayerRendererChromiumImpl(CCLayerTreeHostImplClient* client, LayerRendererChromium* layerRenderer)
1391         : CCLayerTreeHostImpl(client)
1392         , m_layerRenderer(layerRenderer) { }
1393
1394     void drawLayersOnMainThread(CCCompletionEvent* completion, bool* contextLost)
1395     {
1396         ASSERT(isMainThread());
1397
1398         if (m_layerRenderer->rootLayer()) {
1399             m_layerRenderer->drawLayers();
1400             m_layerRenderer->present();
1401
1402             GraphicsContext3D* context = m_layerRenderer->context();
1403             *contextLost = context->getExtensions()->getGraphicsResetStatusARB() != GraphicsContext3D::NO_ERROR;
1404         } else
1405             *contextLost = false;
1406         completion->signal();
1407     }
1408
1409     LayerRendererChromium* m_layerRenderer;
1410 };
1411
1412 class LayerRendererChromiumImplProxy : public CCLayerTreeHostImplProxy {
1413 public:
1414     static PassOwnPtr<LayerRendererChromiumImplProxy> create(LayerRendererChromium* layerRenderer)
1415     {
1416         return adoptPtr(new LayerRendererChromiumImplProxy(layerRenderer));
1417     }
1418
1419     virtual PassOwnPtr<CCLayerTreeHostImpl> createLayerTreeHostImpl()
1420     {
1421         return LayerRendererChromiumImpl::create(this, static_cast<LayerRendererChromium*>(host()));
1422     }
1423
1424 private:
1425     LayerRendererChromiumImplProxy(LayerRendererChromium* layerRenderer)
1426         : CCLayerTreeHostImplProxy(layerRenderer) { }
1427 };
1428
1429 PassOwnPtr<CCLayerTreeHostImplProxy> LayerRendererChromium::createLayerTreeHostImplProxy()
1430 {
1431     OwnPtr<CCLayerTreeHostImplProxy> proxy = LayerRendererChromiumImplProxy::create(this);
1432     proxy->start();
1433     return proxy.release();
1434 }
1435
1436 } // namespace WebCore
1437
1438 #endif // USE(ACCELERATED_COMPOSITING)