1d3d369a1395031ef0d6072df08a2e9d3260ed26
[WebKit-https.git] / Source / WebCore / platform / graphics / chromium / Canvas2DLayerChromium.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 #include "config.h"
32
33 #if USE(ACCELERATED_COMPOSITING)
34
35 #include "Canvas2DLayerChromium.h"
36
37 #include "Extensions3DChromium.h"
38 #include "GraphicsContext3D.h"
39 #include "LayerRendererChromium.h" // For the GLC() macro
40 #include "cc/CCLayerTreeHost.h"
41 #include "cc/CCTextureLayerImpl.h"
42 #include "cc/CCTextureUpdater.h"
43
44 #include "SkCanvas.h"
45
46 namespace WebCore {
47
48 PassRefPtr<Canvas2DLayerChromium> Canvas2DLayerChromium::create(PassRefPtr<GraphicsContext3D> context, const IntSize& size)
49 {
50     return adoptRef(new Canvas2DLayerChromium(context, size));
51 }
52
53 Canvas2DLayerChromium::Canvas2DLayerChromium(PassRefPtr<GraphicsContext3D> context, const IntSize& size)
54     : CanvasLayerChromium()
55     , m_context(context)
56     , m_contextLost(false)
57     , m_size(size)
58     , m_backTextureId(0)
59     , m_fbo(0)
60     , m_useDoubleBuffering(CCProxy::hasImplThread())
61     , m_canvas(0)
62 {
63     if (m_useDoubleBuffering)
64         GLC(m_context, m_fbo = m_context->createFramebuffer());
65 }
66
67 Canvas2DLayerChromium::~Canvas2DLayerChromium()
68 {
69     if (m_useDoubleBuffering && m_fbo)
70        GLC(m_context, m_context->deleteFramebuffer(m_fbo));
71     if (m_context && layerTreeHost())
72         layerTreeHost()->stopRateLimiter(m_context.get());
73 }
74
75 void Canvas2DLayerChromium::setTextureId(unsigned textureId)
76 {
77     m_backTextureId = textureId;
78     setNeedsCommit();
79 }
80
81 void Canvas2DLayerChromium::setNeedsDisplayRect(const FloatRect& dirtyRect)
82 {
83     LayerChromium::setNeedsDisplayRect(dirtyRect);
84
85     if (layerTreeHost())
86         layerTreeHost()->startRateLimiter(m_context.get());
87 }
88
89 bool Canvas2DLayerChromium::drawsContent() const
90 {
91     return LayerChromium::drawsContent() && m_backTextureId && !m_size.isEmpty()
92         && !m_contextLost;
93 }
94
95 void Canvas2DLayerChromium::setCanvas(SkCanvas* canvas)
96 {
97     m_canvas = canvas;
98 }
99
100 void Canvas2DLayerChromium::paintContentsIfDirty(const CCOcclusionTracker* /* occlusion */)
101 {
102     TRACE_EVENT("Canvas2DLayerChromium::paintContentsIfDirty", this, 0);
103     if (!drawsContent())
104         return;
105
106     if (m_useDoubleBuffering && layerTreeHost()) {
107         TextureManager* textureManager = layerTreeHost()->contentsTextureManager();
108         if (m_frontTexture)
109             m_frontTexture->setTextureManager(textureManager);
110         else
111             m_frontTexture = ManagedTexture::create(textureManager);
112         m_frontTexture->reserve(m_size, GraphicsContext3D::RGBA);
113     }
114
115     if (!needsDisplay())
116         return;
117
118     m_needsDisplay = false;
119
120     bool success = m_context->makeContextCurrent();
121     ASSERT_UNUSED(success, success);
122
123     m_contextLost = m_context->getExtensions()->getGraphicsResetStatusARB() != GraphicsContext3D::NO_ERROR;
124     if (m_contextLost)
125         return;
126
127     if (m_canvas) {
128         TRACE_EVENT("SkDeferredCanvas::flush", m_canvas, 0);
129         m_canvas->flush();
130     }
131
132     TRACE_EVENT("GrContext::flush", m_context, 0);
133     m_context->flush();
134 }
135
136 void Canvas2DLayerChromium::updateCompositorResources(GraphicsContext3D* context, CCTextureUpdater& updater)
137 {
138     if (!m_backTextureId || !m_frontTexture || !m_frontTexture->isValid(m_size, GraphicsContext3D::RGBA))
139         return;
140
141     m_frontTexture->bindTexture(context, updater.allocator());
142
143     GLC(context, context->bindFramebuffer(GraphicsContext3D::FRAMEBUFFER, m_fbo));
144     GLC(context, context->framebufferTexture2D(GraphicsContext3D::FRAMEBUFFER, GraphicsContext3D::COLOR_ATTACHMENT0, GraphicsContext3D::TEXTURE_2D, m_backTextureId, 0));
145     // FIXME: The copy operation will fail if the m_backTexture is allocated as BGRA since glCopyTex(Sub)Image2D doesn't
146     //        support the BGRA format. See bug https://bugs.webkit.org/show_bug.cgi?id=75142
147     GLC(context, context->copyTexSubImage2D(GraphicsContext3D::TEXTURE_2D, 0, 0, 0, 0, 0, m_size.width(), m_size.height()));
148     GLC(context, context->bindFramebuffer(GraphicsContext3D::FRAMEBUFFER, 0));
149     GLC(context, context->flush());
150 }
151
152 void Canvas2DLayerChromium::pushPropertiesTo(CCLayerImpl* layer)
153 {
154     CanvasLayerChromium::pushPropertiesTo(layer);
155
156     CCTextureLayerImpl* textureLayer = static_cast<CCTextureLayerImpl*>(layer);
157     if (m_useDoubleBuffering) {
158         if (m_frontTexture && m_frontTexture->isValid(m_size, GraphicsContext3D::RGBA))
159             textureLayer->setTextureId(m_frontTexture->textureId());
160         else
161             textureLayer->setTextureId(0);
162     } else
163         textureLayer->setTextureId(m_backTextureId);
164 }
165
166 void Canvas2DLayerChromium::unreserveContentsTexture()
167 {
168     if (m_useDoubleBuffering)
169         m_frontTexture->unreserve();
170 }
171
172 }
173
174 #endif // USE(ACCELERATED_COMPOSITING)