[NRWT] reftest asserts intermittently on the Qt-WK2 bot
[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 "CanvasLayerTextureUpdater.h"
39 #include "Extensions3DChromium.h"
40 #include "FloatQuad.h"
41 #include "GeometryBinding.h"
42 #include "GraphicsContext3D.h"
43 #include "LayerChromium.h"
44 #include "LayerPainterChromium.h"
45 #include "ManagedTexture.h"
46 #include "NonCompositedContentHost.h"
47 #include "NotImplemented.h"
48 #include "PlatformColor.h"
49 #include "RenderSurfaceChromium.h"
50 #include "TextStream.h"
51 #include "TextureManager.h"
52 #include "TraceEvent.h"
53 #include "TrackingTextureAllocator.h"
54 #include "TreeSynchronizer.h"
55 #include "WebGLLayerChromium.h"
56 #include "cc/CCLayerImpl.h"
57 #include "cc/CCLayerTreeHostCommon.h"
58 #include "cc/CCProxy.h"
59 #if USE(SKIA)
60 #include "Extensions3D.h"
61 #include "GrContext.h"
62 #include "NativeImageSkia.h"
63 #include "PlatformContextSkia.h"
64 #elif USE(CG)
65 #include <CoreGraphics/CGBitmapContext.h>
66 #endif
67 #include <wtf/CurrentTime.h>
68 #include <wtf/MainThread.h>
69
70 using namespace std;
71
72 namespace WebCore {
73
74 namespace {
75
76 static TransformationMatrix orthoMatrix(float left, float right, float bottom, float top)
77 {
78     float deltaX = right - left;
79     float deltaY = top - bottom;
80     TransformationMatrix ortho;
81     if (!deltaX || !deltaY)
82         return ortho;
83     ortho.setM11(2.0f / deltaX);
84     ortho.setM41(-(right + left) / deltaX);
85     ortho.setM22(2.0f / deltaY);
86     ortho.setM42(-(top + bottom) / deltaY);
87
88     // Z component of vertices is always set to zero as we don't use the depth buffer
89     // while drawing.
90     ortho.setM33(0);
91
92     return ortho;
93 }
94
95 static TransformationMatrix screenMatrix(int x, int y, int width, int height)
96 {
97     TransformationMatrix screen;
98
99     // Map to viewport.
100     screen.translate3d(x, y, 0);
101     screen.scale3d(width, height, 0);
102
103     // Map x, y and z to unit square.
104     screen.translate3d(0.5, 0.5, 0.5);
105     screen.scale3d(0.5, 0.5, 0.5);
106
107     return screen;
108 }
109
110 #if USE(SKIA)
111 bool contextSupportsAcceleratedPainting(GraphicsContext3D* context)
112 {
113     WebCore::Extensions3D* extensions = context->getExtensions();
114     if (extensions->supports("GL_EXT_texture_format_BGRA8888"))
115         extensions->ensureEnabled("GL_EXT_texture_format_BGRA8888");
116     else
117         return false;
118
119     if (extensions->supports("GL_EXT_read_format_bgra"))
120         extensions->ensureEnabled("GL_EXT_read_format_bgra");
121     else
122         return false;
123
124     if (!context->grContext())
125         return false;
126
127     return true;
128 }
129 #endif
130
131 } // anonymous namespace
132
133 class LayerRendererSwapBuffersCompleteCallbackAdapter : public Extensions3DChromium::SwapBuffersCompleteCallbackCHROMIUM {
134 public:
135     static PassOwnPtr<LayerRendererSwapBuffersCompleteCallbackAdapter> create(LayerRendererChromium* layerRenderer)
136     {
137         return adoptPtr(new LayerRendererSwapBuffersCompleteCallbackAdapter(layerRenderer));
138     }
139     virtual ~LayerRendererSwapBuffersCompleteCallbackAdapter() { }
140
141     virtual void onSwapBuffersComplete()
142     {
143         m_layerRenderer->onSwapBuffersComplete();
144     }
145
146 private:
147     explicit LayerRendererSwapBuffersCompleteCallbackAdapter(LayerRendererChromium* layerRenderer)
148     {
149         m_layerRenderer = layerRenderer;
150     }
151
152     LayerRendererChromium* m_layerRenderer;
153 };
154
155
156 PassOwnPtr<LayerRendererChromium> LayerRendererChromium::create(CCLayerTreeHostImpl* owner, PassRefPtr<GraphicsContext3D> context)
157 {
158 #if USE(SKIA)
159     if (owner->settings().acceleratePainting && !contextSupportsAcceleratedPainting(context.get()))
160         return nullptr;
161 #endif
162     OwnPtr<LayerRendererChromium> layerRenderer(adoptPtr(new LayerRendererChromium(owner, context)));
163     if (!layerRenderer->initialize())
164         return nullptr;
165
166     return layerRenderer.release();
167 }
168
169 LayerRendererChromium::LayerRendererChromium(CCLayerTreeHostImpl* owner,
170                                              PassRefPtr<GraphicsContext3D> context)
171     : m_owner(owner)
172     , m_currentRenderSurface(0)
173     , m_offscreenFramebufferId(0)
174     , m_context(context)
175     , m_defaultRenderSurface(0)
176     , m_sharedGeometryQuad(FloatRect(-0.5f, -0.5f, 1.0f, 1.0f))
177     , m_isViewportChanged(false)
178 {
179 }
180
181 bool LayerRendererChromium::initialize()
182 {
183     if (!m_context->makeContextCurrent())
184         return false;
185
186     if (settings().acceleratePainting)
187         m_capabilities.usingAcceleratedPainting = true;
188
189     WebCore::Extensions3D* extensions = m_context->getExtensions();
190     m_capabilities.contextHasCachedFrontBuffer = extensions->supports("GL_CHROMIUM_front_buffer_cached");
191     if (m_capabilities.contextHasCachedFrontBuffer)
192         extensions->ensureEnabled("GL_CHROMIUM_front_buffer_cached");
193
194     m_capabilities.usingPostSubBuffer = extensions->supports("GL_CHROMIUM_post_sub_buffer");
195     if (m_capabilities.usingPostSubBuffer)
196         extensions->ensureEnabled("GL_CHROMIUM_post_sub_buffer");
197
198     m_capabilities.usingMapSub = extensions->supports("GL_CHROMIUM_map_sub");
199     if (m_capabilities.usingMapSub)
200         extensions->ensureEnabled("GL_CHROMIUM_map_sub");
201
202     // Use the swapBuffers callback only with the threaded proxy.
203     if (CCProxy::hasImplThread())
204         m_capabilities.usingSwapCompleteCallback = extensions->supports("GL_CHROMIUM_swapbuffers_complete_callback");
205     if (m_capabilities.usingSwapCompleteCallback) {
206         extensions->ensureEnabled("GL_CHROMIUM_swapbuffers_complete_callback");
207         Extensions3DChromium* extensions3DChromium = static_cast<Extensions3DChromium*>(extensions);
208         extensions3DChromium->setSwapBuffersCompleteCallbackCHROMIUM(LayerRendererSwapBuffersCompleteCallbackAdapter::create(this));
209     }
210
211     if (extensions->supports("GL_EXT_texture_format_BGRA8888"))
212         extensions->ensureEnabled("GL_EXT_texture_format_BGRA8888");
213
214     m_capabilities.usingSetVisibility = extensions->supports("GL_CHROMIUM_set_visibility");
215     if (m_capabilities.usingSetVisibility)
216         extensions->ensureEnabled("GL_CHROMIUM_set_visibility");
217
218     if (extensions->supports("GL_CHROMIUM_iosurface")) {
219         ASSERT(extensions->supports("GL_ARB_texture_rectangle"));
220         extensions->ensureEnabled("GL_ARB_texture_rectangle");
221         extensions->ensureEnabled("GL_CHROMIUM_iosurface");
222     }
223
224     GLC(m_context.get(), m_context->getIntegerv(GraphicsContext3D::MAX_TEXTURE_SIZE, &m_capabilities.maxTextureSize));
225     m_capabilities.bestTextureFormat = PlatformColor::bestTextureFormat(m_context.get());
226
227     if (!initializeSharedObjects())
228         return false;
229
230     m_headsUpDisplay = CCHeadsUpDisplay::create(this);
231
232     // Make sure the viewport and context gets initialized, even if it is to zero.
233     viewportChanged();
234     return true;
235 }
236
237 LayerRendererChromium::~LayerRendererChromium()
238 {
239     ASSERT(CCProxy::isImplThread());
240     Extensions3DChromium* extensions3DChromium = static_cast<Extensions3DChromium*>(m_context->getExtensions());
241     extensions3DChromium->setSwapBuffersCompleteCallbackCHROMIUM(nullptr);
242     m_headsUpDisplay.clear(); // Explicitly destroy the HUD before the TextureManager dies.
243     cleanupSharedObjects();
244 }
245
246 void LayerRendererChromium::clearRenderSurfacesOnCCLayerImplRecursive(CCLayerImpl* layer)
247 {
248     for (size_t i = 0; i < layer->children().size(); ++i)
249         clearRenderSurfacesOnCCLayerImplRecursive(layer->children()[i].get());
250     layer->clearRenderSurface();
251 }
252
253 void LayerRendererChromium::close()
254 {
255     if (rootLayer())
256         clearRenderSurfacesOnCCLayerImplRecursive(rootLayer());
257 }
258
259 GraphicsContext3D* LayerRendererChromium::context()
260 {
261     return m_context.get();
262 }
263
264 void LayerRendererChromium::debugGLCall(GraphicsContext3D* context, const char* command, const char* file, int line)
265 {
266     unsigned long error = context->getError();
267     if (error != GraphicsContext3D::NO_ERROR)
268         LOG_ERROR("GL command failed: File: %s\n\tLine %d\n\tcommand: %s, error %x\n", file, line, command, static_cast<int>(error));
269 }
270
271 void LayerRendererChromium::setVisible(bool visible)
272 {
273     if (!visible)
274         releaseRenderSurfaceTextures();
275     if (m_capabilities.usingSetVisibility) {
276         Extensions3DChromium* extensions3DChromium = static_cast<Extensions3DChromium*>(m_context->getExtensions());
277         extensions3DChromium->setVisibilityCHROMIUM(visible);
278     }
279 }
280
281 void LayerRendererChromium::releaseRenderSurfaceTextures()
282 {
283     if (m_renderSurfaceTextureManager)
284         m_renderSurfaceTextureManager->evictAndDeleteAllTextures(m_renderSurfaceTextureAllocator.get());
285 }
286
287 void LayerRendererChromium::viewportChanged()
288 {
289     m_isViewportChanged = true;
290
291     // Reset the current render surface to force an update of the viewport and
292     // projection matrix next time useRenderSurface is called.
293     m_currentRenderSurface = 0;
294 }
295
296 void LayerRendererChromium::drawLayers()
297 {
298     // FIXME: use the frame begin time from the overall compositor scheduler.
299     // This value is currently inaccessible because it is up in Chromium's
300     // RenderWidget.
301     m_headsUpDisplay->onFrameBegin(currentTime());
302
303     if (!rootLayer())
304         return;
305
306     size_t contentsMemoryUseBytes = m_contentsTextureAllocator->currentMemoryUseBytes();
307     m_renderSurfaceTextureManager->setMemoryLimitBytes(TextureManager::highLimitBytes() - contentsMemoryUseBytes);
308     drawLayersInternal();
309
310     if (TextureManager::reclaimLimitBytes() > contentsMemoryUseBytes)
311         m_renderSurfaceTextureManager->reduceMemoryToLimit(TextureManager::reclaimLimitBytes() - contentsMemoryUseBytes);
312     else
313         m_renderSurfaceTextureManager->reduceMemoryToLimit(0);
314     m_renderSurfaceTextureManager->deleteEvictedTextures(m_renderSurfaceTextureAllocator.get());
315
316     if (settings().compositeOffscreen)
317         copyOffscreenTextureToDisplay();
318 }
319
320 void LayerRendererChromium::drawLayersOntoRenderSurfaces(CCLayerImpl* rootDrawLayer, const CCLayerList& renderSurfaceLayerList)
321 {
322     TRACE_EVENT("LayerRendererChromium::drawLayersOntoRenderSurfaces", this, 0);
323
324     // Update the contents of the render surfaces. We traverse the render surfaces
325     // from back to front to guarantee that nested render surfaces get rendered in
326     // the correct order.
327     for (int surfaceIndex = renderSurfaceLayerList.size() - 1; surfaceIndex >= 0 ; --surfaceIndex) {
328         CCLayerImpl* renderSurfaceLayer = renderSurfaceLayerList[surfaceIndex].get();
329         CCRenderSurface* renderSurface = renderSurfaceLayer->renderSurface();
330         ASSERT(renderSurface);
331         ASSERT(renderSurface->drawOpacity());
332
333         if (useRenderSurface(renderSurface)) {
334
335             if (renderSurfaceLayer != rootDrawLayer) {
336                 GLC(m_context.get(), m_context->disable(GraphicsContext3D::SCISSOR_TEST));
337                 GLC(m_context.get(), m_context->clearColor(0, 0, 0, 0));
338                 GLC(m_context.get(), m_context->clear(GraphicsContext3D::COLOR_BUFFER_BIT));
339                 GLC(m_context.get(), m_context->enable(GraphicsContext3D::SCISSOR_TEST));
340             }
341
342             const CCLayerList& layerList = renderSurface->layerList();
343             for (unsigned layerIndex = 0; layerIndex < layerList.size(); ++layerIndex)
344                 drawLayer(layerList[layerIndex].get(), renderSurface);
345         }
346     }
347
348     // The next frame should start by assuming nothing has changed, and changes are noted as they occur.
349     rootDrawLayer->resetAllChangeTrackingForSubtree();
350 }
351
352
353 void LayerRendererChromium::drawLayersInternal()
354 {
355     if (viewportSize().isEmpty() || !rootLayer())
356         return;
357
358     TRACE_EVENT("LayerRendererChromium::drawLayers", this, 0);
359     if (m_isViewportChanged) {
360         // Only reshape when we know we are going to draw. Otherwise, the reshape
361         // can leave the window at the wrong size if we never draw and the proper
362         // viewport size is never set.
363         m_isViewportChanged = false;
364         m_context->reshape(viewportWidth(), viewportHeight());
365     }
366
367     CCLayerImpl* rootDrawLayer = rootLayer();
368     makeContextCurrent();
369
370     if (!rootDrawLayer->renderSurface())
371         rootDrawLayer->createRenderSurface();
372     rootDrawLayer->renderSurface()->setContentRect(IntRect(IntPoint(), viewportSize()));
373
374     rootDrawLayer->setClipRect(IntRect(IntPoint(), viewportSize()));
375
376     CCLayerList renderSurfaceLayerList;
377     renderSurfaceLayerList.append(rootDrawLayer);
378
379     m_defaultRenderSurface = rootDrawLayer->renderSurface();
380     m_defaultRenderSurface->clearLayerList();
381
382     TransformationMatrix identityMatrix;
383     {
384         TRACE_EVENT("LayerRendererChromium::drawLayersInternal::calcDrawEtc", this, 0);
385         CCLayerTreeHostCommon::calculateDrawTransformsAndVisibility(rootDrawLayer, rootDrawLayer, identityMatrix, identityMatrix, renderSurfaceLayerList, m_defaultRenderSurface->layerList(), &m_layerSorter, m_capabilities.maxTextureSize);
386     }
387
388     // The GL viewport covers the entire visible area, including the scrollbars.
389     GLC(m_context.get(), m_context->viewport(0, 0, viewportWidth(), viewportHeight()));
390     m_windowMatrix = screenMatrix(0, 0, viewportWidth(), viewportHeight());
391
392     // Bind the common vertex attributes used for drawing all the layers.
393     m_sharedGeometry->prepareForDraw();
394
395     GLC(m_context.get(), m_context->disable(GraphicsContext3D::SCISSOR_TEST));
396     GLC(m_context.get(), m_context->disable(GraphicsContext3D::DEPTH_TEST));
397     GLC(m_context.get(), m_context->disable(GraphicsContext3D::CULL_FACE));
398
399     useRenderSurface(m_defaultRenderSurface);
400
401     // Clear to blue to make it easier to spot unrendered regions.
402     m_context->clearColor(0, 0, 1, 1);
403     m_context->colorMask(true, true, true, true);
404     m_context->clear(GraphicsContext3D::COLOR_BUFFER_BIT);
405
406     GLC(m_context.get(), m_context->enable(GraphicsContext3D::BLEND));
407     GLC(m_context.get(), m_context->blendFunc(GraphicsContext3D::ONE, GraphicsContext3D::ONE_MINUS_SRC_ALPHA));
408     GLC(m_context.get(), m_context->enable(GraphicsContext3D::SCISSOR_TEST));
409
410     drawLayersOntoRenderSurfaces(rootDrawLayer, renderSurfaceLayerList);
411
412     if (m_headsUpDisplay->enabled()) {
413         GLC(m_context.get(), m_context->enable(GraphicsContext3D::BLEND));
414         GLC(m_context.get(), m_context->blendFunc(GraphicsContext3D::ONE, GraphicsContext3D::ONE_MINUS_SRC_ALPHA));
415         GLC(m_context.get(), m_context->disable(GraphicsContext3D::SCISSOR_TEST));
416         useRenderSurface(m_defaultRenderSurface);
417         m_headsUpDisplay->draw();
418     }
419
420     GLC(m_context.get(), m_context->disable(GraphicsContext3D::SCISSOR_TEST));
421     GLC(m_context.get(), m_context->disable(GraphicsContext3D::BLEND));
422 }
423
424 void LayerRendererChromium::toGLMatrix(float* flattened, const TransformationMatrix& m)
425 {
426     flattened[0] = m.m11();
427     flattened[1] = m.m12();
428     flattened[2] = m.m13();
429     flattened[3] = m.m14();
430     flattened[4] = m.m21();
431     flattened[5] = m.m22();
432     flattened[6] = m.m23();
433     flattened[7] = m.m24();
434     flattened[8] = m.m31();
435     flattened[9] = m.m32();
436     flattened[10] = m.m33();
437     flattened[11] = m.m34();
438     flattened[12] = m.m41();
439     flattened[13] = m.m42();
440     flattened[14] = m.m43();
441     flattened[15] = m.m44();
442 }
443
444 void LayerRendererChromium::drawTexturedQuad(const TransformationMatrix& drawMatrix,
445                                              float width, float height, float opacity, const FloatQuad& quad,
446                                              int matrixLocation, int alphaLocation, int quadLocation)
447 {
448     static float glMatrix[16];
449
450     TransformationMatrix renderMatrix = drawMatrix;
451
452     // Apply a scaling factor to size the quad from 1x1 to its intended size.
453     renderMatrix.scale3d(width, height, 1);
454
455     // Apply the projection matrix before sending the transform over to the shader.
456     toGLMatrix(&glMatrix[0], m_projectionMatrix * renderMatrix);
457
458     GLC(m_context, m_context->uniformMatrix4fv(matrixLocation, false, &glMatrix[0], 1));
459
460     if (quadLocation != -1) {
461         float point[8];
462         point[0] = quad.p1().x();
463         point[1] = quad.p1().y();
464         point[2] = quad.p2().x();
465         point[3] = quad.p2().y();
466         point[4] = quad.p3().x();
467         point[5] = quad.p3().y();
468         point[6] = quad.p4().x();
469         point[7] = quad.p4().y();
470         GLC(m_context, m_context->uniform2fv(quadLocation, point, 4));
471     }
472
473     if (alphaLocation != -1)
474         GLC(m_context, m_context->uniform1f(alphaLocation, opacity));
475
476     GLC(m_context, m_context->drawElements(GraphicsContext3D::TRIANGLES, 6, GraphicsContext3D::UNSIGNED_SHORT, 0));
477 }
478
479 void LayerRendererChromium::finish()
480 {
481     TRACE_EVENT("LayerRendererChromium::finish", this, 0);
482     m_context->finish();
483 }
484
485 void LayerRendererChromium::swapBuffers()
486 {
487     TRACE_EVENT("LayerRendererChromium::swapBuffers", this, 0);
488     // We're done! Time to swapbuffers!
489
490     // Note that currently this has the same effect as swapBuffers; we should
491     // consider exposing a different entry point on GraphicsContext3D.
492     m_context->prepareTexture();
493
494     m_headsUpDisplay->onSwapBuffers();
495 }
496
497 void LayerRendererChromium::onSwapBuffersComplete()
498 {
499     m_owner->onSwapBuffersComplete();
500 }
501
502 void LayerRendererChromium::getFramebufferPixels(void *pixels, const IntRect& rect)
503 {
504     ASSERT(rect.maxX() <= viewportWidth() && rect.maxY() <= viewportHeight());
505
506     if (!pixels)
507         return;
508
509     makeContextCurrent();
510
511     GLC(m_context.get(), m_context->readPixels(rect.x(), rect.y(), rect.width(), rect.height(),
512                                          GraphicsContext3D::RGBA, GraphicsContext3D::UNSIGNED_BYTE, pixels));
513 }
514
515 // Returns true if any part of the layer falls within the visibleRect
516 bool LayerRendererChromium::isLayerVisible(LayerChromium* layer, const TransformationMatrix& matrix, const IntRect& visibleRect)
517 {
518     // Form the matrix used by the shader to map the corners of the layer's
519     // bounds into clip space.
520     TransformationMatrix renderMatrix = matrix;
521     renderMatrix.scale3d(layer->bounds().width(), layer->bounds().height(), 1);
522     renderMatrix = m_projectionMatrix * renderMatrix;
523
524     FloatRect layerRect(-0.5, -0.5, 1, 1);
525     FloatRect mappedRect = renderMatrix.mapRect(layerRect);
526
527     // The layer is visible if it intersects any part of a rectangle whose origin
528     // is at (-1, -1) and size is 2x2.
529     return mappedRect.intersects(FloatRect(-1, -1, 2, 2));
530 }
531
532 ManagedTexture* LayerRendererChromium::getOffscreenLayerTexture()
533 {
534     return settings().compositeOffscreen && rootLayer() ? rootLayer()->renderSurface()->contentsTexture() : 0;
535 }
536
537 void LayerRendererChromium::copyOffscreenTextureToDisplay()
538 {
539     if (settings().compositeOffscreen) {
540         makeContextCurrent();
541
542         useRenderSurface(0);
543         TransformationMatrix drawTransform;
544         drawTransform.translate3d(0.5 * m_defaultRenderSurface->contentRect().width(), 0.5 * m_defaultRenderSurface->contentRect().height(), 0);
545         m_defaultRenderSurface->setDrawTransform(drawTransform);
546         m_defaultRenderSurface->setDrawOpacity(1);
547         m_defaultRenderSurface->draw(this, m_defaultRenderSurface->contentRect());
548     }
549 }
550
551 bool LayerRendererChromium::useRenderSurface(CCRenderSurface* renderSurface)
552 {
553     if (m_currentRenderSurface == renderSurface)
554         return true;
555
556     m_currentRenderSurface = renderSurface;
557
558     if ((renderSurface == m_defaultRenderSurface && !settings().compositeOffscreen) || (!renderSurface && settings().compositeOffscreen)) {
559         GLC(m_context.get(), m_context->bindFramebuffer(GraphicsContext3D::FRAMEBUFFER, 0));
560         if (renderSurface)
561             setDrawViewportRect(renderSurface->contentRect(), true);
562         else
563             setDrawViewportRect(m_defaultRenderSurface->contentRect(), true);
564         return true;
565     }
566
567     GLC(m_context.get(), m_context->bindFramebuffer(GraphicsContext3D::FRAMEBUFFER, m_offscreenFramebufferId));
568
569     if (!renderSurface->prepareContentsTexture(this))
570         return false;
571
572     renderSurface->contentsTexture()->framebufferTexture2D(m_context.get(), m_renderSurfaceTextureAllocator.get());
573
574 #if !defined ( NDEBUG )
575     if (m_context->checkFramebufferStatus(GraphicsContext3D::FRAMEBUFFER) != GraphicsContext3D::FRAMEBUFFER_COMPLETE) {
576         ASSERT_NOT_REACHED();
577         return false;
578     }
579 #endif
580
581     setDrawViewportRect(renderSurface->contentRect(), false);
582     return true;
583 }
584
585 void LayerRendererChromium::drawLayer(CCLayerImpl* layer, CCRenderSurface* targetSurface)
586 {
587     if (CCLayerTreeHostCommon::renderSurfaceContributesToTarget<CCLayerImpl>(layer, targetSurface->owningLayerId())) {
588         layer->renderSurface()->draw(this, layer->getDrawRect());
589         layer->renderSurface()->releaseContentsTexture();
590         return;
591     }
592
593     if (layer->visibleLayerRect().isEmpty())
594         return;
595
596     if (layer->usesLayerClipping())
597         setScissorToRect(layer->clipRect());
598     else
599         GLC(m_context.get(), m_context->disable(GraphicsContext3D::SCISSOR_TEST));
600
601     bool opaque = layer->opaque() && layer->drawOpacity() == 1;
602     if (opaque)
603         GLC(m_context.get(), m_context->disable(GraphicsContext3D::BLEND));
604
605     layer->draw(this);
606
607     if (opaque)
608         GLC(m_context.get(), m_context->enable(GraphicsContext3D::BLEND));
609
610     // Draw the debug border if there is one.
611     layer->drawDebugBorder(this);
612 }
613
614 // Sets the scissor region to the given rectangle. The coordinate system for the
615 // scissorRect has its origin at the top left corner of the current visible rect.
616 void LayerRendererChromium::setScissorToRect(const IntRect& scissorRect)
617 {
618     IntRect contentRect = (m_currentRenderSurface ? m_currentRenderSurface->contentRect() : m_defaultRenderSurface->contentRect());
619
620     GLC(m_context.get(), m_context->enable(GraphicsContext3D::SCISSOR_TEST));
621
622     // The scissor coordinates must be supplied in viewport space so we need to offset
623     // by the relative position of the top left corner of the current render surface.
624     int scissorX = scissorRect.x() - contentRect.x();
625     // When rendering to the default render surface we're rendering upside down so the top
626     // of the GL scissor is the bottom of our layer.
627     // But, if rendering to offscreen texture, we reverse our sense of 'upside down'.
628     int scissorY;
629     if (m_currentRenderSurface == m_defaultRenderSurface && !settings().compositeOffscreen)
630         scissorY = m_currentRenderSurface->contentRect().height() - (scissorRect.maxY() - m_currentRenderSurface->contentRect().y());
631     else
632         scissorY = scissorRect.y() - contentRect.y();
633     GLC(m_context.get(), m_context->scissor(scissorX, scissorY, scissorRect.width(), scissorRect.height()));
634 }
635
636 bool LayerRendererChromium::makeContextCurrent()
637 {
638     return m_context->makeContextCurrent();
639 }
640
641 // Sets the coordinate range of content that ends being drawn onto the target render surface.
642 // The target render surface is assumed to have an origin at 0, 0 and the width and height of
643 // of the drawRect.
644 void LayerRendererChromium::setDrawViewportRect(const IntRect& drawRect, bool flipY)
645 {
646     if (flipY)
647         m_projectionMatrix = orthoMatrix(drawRect.x(), drawRect.maxX(), drawRect.maxY(), drawRect.y());
648     else
649         m_projectionMatrix = orthoMatrix(drawRect.x(), drawRect.maxX(), drawRect.y(), drawRect.maxY());
650     GLC(m_context.get(), m_context->viewport(0, 0, drawRect.width(), drawRect.height()));
651     m_windowMatrix = screenMatrix(0, 0, drawRect.width(), drawRect.height());
652 }
653
654
655 bool LayerRendererChromium::initializeSharedObjects()
656 {
657     TRACE_EVENT("LayerRendererChromium::initializeSharedObjects", this, 0);
658     makeContextCurrent();
659
660     // Create an FBO for doing offscreen rendering.
661     GLC(m_context.get(), m_offscreenFramebufferId = m_context->createFramebuffer());
662
663     // We will always need these programs to render, so create the programs eagerly so that the shader compilation can
664     // start while we do other work. Other programs are created lazily on first access.
665     m_sharedGeometry = adoptPtr(new GeometryBinding(m_context.get()));
666     m_renderSurfaceProgram = adoptPtr(new CCRenderSurface::Program(m_context.get()));
667     m_tilerProgram = adoptPtr(new CCTiledLayerImpl::Program(m_context.get()));
668     m_tilerProgramOpaque = adoptPtr(new CCTiledLayerImpl::ProgramOpaque(m_context.get()));
669
670     GLC(m_context.get(), m_context->flush());
671
672     m_renderSurfaceTextureManager = TextureManager::create(TextureManager::highLimitBytes(), m_capabilities.maxTextureSize);
673     m_contentsTextureAllocator = TrackingTextureAllocator::create(m_context.get());
674     m_renderSurfaceTextureAllocator = TrackingTextureAllocator::create(m_context.get());
675     return true;
676 }
677
678 const LayerChromium::BorderProgram* LayerRendererChromium::borderProgram()
679 {
680     if (!m_borderProgram)
681         m_borderProgram = adoptPtr(new LayerChromium::BorderProgram(m_context.get()));
682     if (!m_borderProgram->initialized()) {
683         TRACE_EVENT("LayerRendererChromium::borderProgram::initialize", this, 0);
684         m_borderProgram->initialize(m_context.get());
685     }
686     return m_borderProgram.get();
687 }
688
689 const CCHeadsUpDisplay::Program* LayerRendererChromium::headsUpDisplayProgram()
690 {
691     if (!m_headsUpDisplayProgram)
692         m_headsUpDisplayProgram = adoptPtr(new CCHeadsUpDisplay::Program(m_context.get()));
693     if (!m_headsUpDisplayProgram->initialized()) {
694         TRACE_EVENT("LayerRendererChromium::headsUpDisplayProgram::initialize", this, 0);
695         m_headsUpDisplayProgram->initialize(m_context.get());
696     }
697     return m_headsUpDisplayProgram.get();
698 }
699
700 const CCRenderSurface::Program* LayerRendererChromium::renderSurfaceProgram()
701 {
702     ASSERT(m_renderSurfaceProgram);
703     if (!m_renderSurfaceProgram->initialized()) {
704         TRACE_EVENT("LayerRendererChromium::renderSurfaceProgram::initialize", this, 0);
705         m_renderSurfaceProgram->initialize(m_context.get());
706     }
707     return m_renderSurfaceProgram.get();
708 }
709
710 const CCRenderSurface::ProgramAA* LayerRendererChromium::renderSurfaceProgramAA()
711 {
712     if (!m_renderSurfaceProgramAA)
713         m_renderSurfaceProgramAA = adoptPtr(new CCRenderSurface::ProgramAA(m_context.get()));
714     if (!m_renderSurfaceProgramAA->initialized()) {
715         TRACE_EVENT("LayerRendererChromium::renderSurfaceProgramAA::initialize", this, 0);
716         m_renderSurfaceProgramAA->initialize(m_context.get());
717     }
718     return m_renderSurfaceProgramAA.get();
719 }
720
721 const CCRenderSurface::MaskProgram* LayerRendererChromium::renderSurfaceMaskProgram()
722 {
723     if (!m_renderSurfaceMaskProgram)
724         m_renderSurfaceMaskProgram = adoptPtr(new CCRenderSurface::MaskProgram(m_context.get()));
725     if (!m_renderSurfaceMaskProgram->initialized()) {
726         TRACE_EVENT("LayerRendererChromium::renderSurfaceMaskProgram::initialize", this, 0);
727         m_renderSurfaceMaskProgram->initialize(m_context.get());
728     }
729     return m_renderSurfaceMaskProgram.get();
730 }
731
732 const CCRenderSurface::MaskProgramAA* LayerRendererChromium::renderSurfaceMaskProgramAA()
733 {
734     if (!m_renderSurfaceMaskProgramAA)
735         m_renderSurfaceMaskProgramAA = adoptPtr(new CCRenderSurface::MaskProgramAA(m_context.get()));
736     if (!m_renderSurfaceMaskProgramAA->initialized()) {
737         TRACE_EVENT("LayerRendererChromium::renderSurfaceMaskProgramAA::initialize", this, 0);
738         m_renderSurfaceMaskProgramAA->initialize(m_context.get());
739     }
740     return m_renderSurfaceMaskProgramAA.get();
741 }
742
743 const CCTiledLayerImpl::Program* LayerRendererChromium::tilerProgram()
744 {
745     ASSERT(m_tilerProgram);
746     if (!m_tilerProgram->initialized()) {
747         TRACE_EVENT("LayerRendererChromium::tilerProgram::initialize", this, 0);
748         m_tilerProgram->initialize(m_context.get());
749     }
750     return m_tilerProgram.get();
751 }
752
753 const CCTiledLayerImpl::ProgramOpaque* LayerRendererChromium::tilerProgramOpaque()
754 {
755     ASSERT(m_tilerProgramOpaque);
756     if (!m_tilerProgramOpaque->initialized()) {
757         TRACE_EVENT("LayerRendererChromium::tilerProgramOpaque::initialize", this, 0);
758         m_tilerProgramOpaque->initialize(m_context.get());
759     }
760     return m_tilerProgramOpaque.get();
761 }
762
763 const CCTiledLayerImpl::ProgramAA* LayerRendererChromium::tilerProgramAA()
764 {
765     if (!m_tilerProgramAA)
766         m_tilerProgramAA = adoptPtr(new CCTiledLayerImpl::ProgramAA(m_context.get()));
767     if (!m_tilerProgramAA->initialized()) {
768         TRACE_EVENT("LayerRendererChromium::tilerProgramAA::initialize", this, 0);
769         m_tilerProgramAA->initialize(m_context.get());
770     }
771     return m_tilerProgramAA.get();
772 }
773
774 const CCTiledLayerImpl::ProgramSwizzle* LayerRendererChromium::tilerProgramSwizzle()
775 {
776     if (!m_tilerProgramSwizzle)
777         m_tilerProgramSwizzle = adoptPtr(new CCTiledLayerImpl::ProgramSwizzle(m_context.get()));
778     if (!m_tilerProgramSwizzle->initialized()) {
779         TRACE_EVENT("LayerRendererChromium::tilerProgramSwizzle::initialize", this, 0);
780         m_tilerProgramSwizzle->initialize(m_context.get());
781     }
782     return m_tilerProgramSwizzle.get();
783 }
784
785 const CCTiledLayerImpl::ProgramSwizzleOpaque* LayerRendererChromium::tilerProgramSwizzleOpaque()
786 {
787     if (!m_tilerProgramSwizzleOpaque)
788         m_tilerProgramSwizzleOpaque = adoptPtr(new CCTiledLayerImpl::ProgramSwizzleOpaque(m_context.get()));
789     if (!m_tilerProgramSwizzleOpaque->initialized()) {
790         TRACE_EVENT("LayerRendererChromium::tilerProgramSwizzleOpaque::initialize", this, 0);
791         m_tilerProgramSwizzleOpaque->initialize(m_context.get());
792     }
793     return m_tilerProgramSwizzleOpaque.get();
794 }
795
796 const CCTiledLayerImpl::ProgramSwizzleAA* LayerRendererChromium::tilerProgramSwizzleAA()
797 {
798     if (!m_tilerProgramSwizzleAA)
799         m_tilerProgramSwizzleAA = adoptPtr(new CCTiledLayerImpl::ProgramSwizzleAA(m_context.get()));
800     if (!m_tilerProgramSwizzleAA->initialized()) {
801         TRACE_EVENT("LayerRendererChromium::tilerProgramSwizzleAA::initialize", this, 0);
802         m_tilerProgramSwizzleAA->initialize(m_context.get());
803     }
804     return m_tilerProgramSwizzleAA.get();
805 }
806
807 const CCCanvasLayerImpl::Program* LayerRendererChromium::canvasLayerProgram()
808 {
809     if (!m_canvasLayerProgram)
810         m_canvasLayerProgram = adoptPtr(new CCCanvasLayerImpl::Program(m_context.get()));
811     if (!m_canvasLayerProgram->initialized()) {
812         TRACE_EVENT("LayerRendererChromium::canvasLayerProgram::initialize", this, 0);
813         m_canvasLayerProgram->initialize(m_context.get());
814     }
815     return m_canvasLayerProgram.get();
816 }
817
818 const CCPluginLayerImpl::Program* LayerRendererChromium::pluginLayerProgram()
819 {
820     if (!m_pluginLayerProgram)
821         m_pluginLayerProgram = adoptPtr(new CCPluginLayerImpl::Program(m_context.get()));
822     if (!m_pluginLayerProgram->initialized()) {
823         TRACE_EVENT("LayerRendererChromium::pluginLayerProgram::initialize", this, 0);
824         m_pluginLayerProgram->initialize(m_context.get());
825     }
826     return m_pluginLayerProgram.get();
827 }
828
829 const CCPluginLayerImpl::ProgramFlip* LayerRendererChromium::pluginLayerProgramFlip()
830 {
831     if (!m_pluginLayerProgramFlip)
832         m_pluginLayerProgramFlip = adoptPtr(new CCPluginLayerImpl::ProgramFlip(m_context.get()));
833     if (!m_pluginLayerProgramFlip->initialized()) {
834         TRACE_EVENT("LayerRendererChromium::pluginLayerProgramFlip::initialize", this, 0);
835         m_pluginLayerProgramFlip->initialize(m_context.get());
836     }
837     return m_pluginLayerProgramFlip.get();
838 }
839
840 const CCPluginLayerImpl::TexRectProgram* LayerRendererChromium::pluginLayerTexRectProgram()
841 {
842     if (!m_pluginLayerTexRectProgram)
843         m_pluginLayerTexRectProgram = adoptPtr(new CCPluginLayerImpl::TexRectProgram(m_context.get()));
844     if (!m_pluginLayerTexRectProgram->initialized()) {
845         TRACE_EVENT("LayerRendererChromium::pluginLayerTexRectProgram::initialize", this, 0);
846         m_pluginLayerTexRectProgram->initialize(m_context.get());
847     }
848     return m_pluginLayerTexRectProgram.get();
849 }
850
851 const CCPluginLayerImpl::TexRectProgramFlip* LayerRendererChromium::pluginLayerTexRectProgramFlip()
852 {
853     if (!m_pluginLayerTexRectProgramFlip)
854         m_pluginLayerTexRectProgramFlip = adoptPtr(new CCPluginLayerImpl::TexRectProgramFlip(m_context.get()));
855     if (!m_pluginLayerTexRectProgramFlip->initialized()) {
856         TRACE_EVENT("LayerRendererChromium::pluginLayerTexRectProgramFlip::initialize", this, 0);
857         m_pluginLayerTexRectProgramFlip->initialize(m_context.get());
858     }
859     return m_pluginLayerTexRectProgramFlip.get();
860 }
861
862 const CCVideoLayerImpl::RGBAProgram* LayerRendererChromium::videoLayerRGBAProgram()
863 {
864     if (!m_videoLayerRGBAProgram)
865         m_videoLayerRGBAProgram = adoptPtr(new CCVideoLayerImpl::RGBAProgram(m_context.get()));
866     if (!m_videoLayerRGBAProgram->initialized()) {
867         TRACE_EVENT("LayerRendererChromium::videoLayerRGBAProgram::initialize", this, 0);
868         m_videoLayerRGBAProgram->initialize(m_context.get());
869     }
870     return m_videoLayerRGBAProgram.get();
871 }
872
873 const CCVideoLayerImpl::YUVProgram* LayerRendererChromium::videoLayerYUVProgram()
874 {
875     if (!m_videoLayerYUVProgram)
876         m_videoLayerYUVProgram = adoptPtr(new CCVideoLayerImpl::YUVProgram(m_context.get()));
877     if (!m_videoLayerYUVProgram->initialized()) {
878         TRACE_EVENT("LayerRendererChromium::videoLayerYUVProgram::initialize", this, 0);
879         m_videoLayerYUVProgram->initialize(m_context.get());
880     }
881     return m_videoLayerYUVProgram.get();
882 }
883
884 const CCVideoLayerImpl::NativeTextureProgram* LayerRendererChromium::videoLayerNativeTextureProgram()
885 {
886     if (!m_videoLayerNativeTextureProgram)
887         m_videoLayerNativeTextureProgram = adoptPtr(new CCVideoLayerImpl::NativeTextureProgram(m_context.get()));
888     if (!m_videoLayerNativeTextureProgram->initialized()) {
889         TRACE_EVENT("LayerRendererChromium::videoLayerNativeTextureProgram::initialize", this, 0);
890         m_videoLayerNativeTextureProgram->initialize(m_context.get());
891     }
892     return m_videoLayerNativeTextureProgram.get();
893 }
894
895
896 void LayerRendererChromium::cleanupSharedObjects()
897 {
898     makeContextCurrent();
899
900     m_sharedGeometry.clear();
901
902     if (m_borderProgram)
903         m_borderProgram->cleanup(m_context.get());
904     if (m_headsUpDisplayProgram)
905         m_headsUpDisplayProgram->cleanup(m_context.get());
906     if (m_tilerProgram)
907         m_tilerProgram->cleanup(m_context.get());
908     if (m_tilerProgramOpaque)
909         m_tilerProgramOpaque->cleanup(m_context.get());
910     if (m_tilerProgramAA)
911         m_tilerProgramAA->cleanup(m_context.get());
912     if (m_tilerProgramSwizzle)
913         m_tilerProgramSwizzle->cleanup(m_context.get());
914     if (m_tilerProgramSwizzleOpaque)
915         m_tilerProgramSwizzleOpaque->cleanup(m_context.get());
916     if (m_tilerProgramSwizzleAA)
917         m_tilerProgramSwizzleAA->cleanup(m_context.get());
918     if (m_canvasLayerProgram)
919         m_canvasLayerProgram->cleanup(m_context.get());
920     if (m_pluginLayerProgram)
921         m_pluginLayerProgram->cleanup(m_context.get());
922     if (m_pluginLayerProgramFlip)
923         m_pluginLayerProgramFlip->cleanup(m_context.get());
924     if (m_renderSurfaceMaskProgram)
925         m_renderSurfaceMaskProgram->cleanup(m_context.get());
926     if (m_renderSurfaceMaskProgramAA)
927         m_renderSurfaceMaskProgramAA->cleanup(m_context.get());
928     if (m_renderSurfaceProgram)
929         m_renderSurfaceProgram->cleanup(m_context.get());
930     if (m_renderSurfaceProgramAA)
931         m_renderSurfaceProgramAA->cleanup(m_context.get());
932     if (m_videoLayerRGBAProgram)
933         m_videoLayerRGBAProgram->cleanup(m_context.get());
934     if (m_videoLayerYUVProgram)
935         m_videoLayerYUVProgram->cleanup(m_context.get());
936
937     m_borderProgram.clear();
938     m_headsUpDisplayProgram.clear();
939     m_tilerProgram.clear();
940     m_tilerProgramOpaque.clear();
941     m_tilerProgramAA.clear();
942     m_tilerProgramSwizzle.clear();
943     m_tilerProgramSwizzleOpaque.clear();
944     m_tilerProgramSwizzleAA.clear();
945     m_canvasLayerProgram.clear();
946     m_pluginLayerProgram.clear();
947     m_pluginLayerProgramFlip.clear();
948     m_renderSurfaceMaskProgram.clear();
949     m_renderSurfaceMaskProgramAA.clear();
950     m_renderSurfaceProgram.clear();
951     m_renderSurfaceProgramAA.clear();
952     m_videoLayerRGBAProgram.clear();
953     m_videoLayerYUVProgram.clear();
954     if (m_offscreenFramebufferId)
955         GLC(m_context.get(), m_context->deleteFramebuffer(m_offscreenFramebufferId));
956
957     releaseRenderSurfaceTextures();
958 }
959
960 String LayerRendererChromium::layerTreeAsText() const
961 {
962     TextStream ts;
963     if (rootLayer()) {
964         ts << rootLayer()->layerTreeAsText();
965         ts << "RenderSurfaces:\n";
966         dumpRenderSurfaces(ts, 1, rootLayer());
967     }
968     return ts.release();
969 }
970
971 void LayerRendererChromium::dumpRenderSurfaces(TextStream& ts, int indent, const CCLayerImpl* layer) const
972 {
973     if (layer->renderSurface())
974         layer->renderSurface()->dumpSurface(ts, indent);
975
976     for (size_t i = 0; i < layer->children().size(); ++i)
977         dumpRenderSurfaces(ts, indent, layer->children()[i].get());
978 }
979
980 bool LayerRendererChromium::isContextLost()
981 {
982     return (m_context.get()->getExtensions()->getGraphicsResetStatusARB() != GraphicsContext3D::NO_ERROR);
983 }
984
985 } // namespace WebCore
986
987 #endif // USE(ACCELERATED_COMPOSITING)