Unreviewed. Build fix for !ENABLE(JIT) after r119441.
[WebKit.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 "TextureCopier.h"
41 #include "cc/CCLayerTreeHost.h"
42 #include "cc/CCTextureLayerImpl.h"
43 #include "cc/CCTextureUpdater.h"
44
45 #include "SkCanvas.h"
46
47 namespace WebCore {
48
49 PassRefPtr<Canvas2DLayerChromium> Canvas2DLayerChromium::create(PassRefPtr<GraphicsContext3D> context, const IntSize& size, DeferralMode deferralMode)
50 {
51     return adoptRef(new Canvas2DLayerChromium(context, size, deferralMode));
52 }
53
54 Canvas2DLayerChromium::Canvas2DLayerChromium(PassRefPtr<GraphicsContext3D> context, const IntSize& size, DeferralMode deferralMode)
55     : CanvasLayerChromium()
56     , m_context(context)
57     , m_contextLost(false)
58     , m_size(size)
59     , m_backTextureId(0)
60     , m_canvas(0)
61     , m_deferralMode(deferralMode)
62 {
63     // FIXME: We currently turn off double buffering when canvas rendering is
64     // deferred. What we should be doing is to use a smarter heuristic based
65     // on GPU resource monitoring and other factors to chose between single
66     // and double buffering.
67     m_useDoubleBuffering = CCProxy::hasImplThread() && deferralMode == NonDeferred;
68
69     // The threaded compositor is self rate-limiting when rendering
70     // to a single buffered canvas layer.
71     m_useRateLimiter = !CCProxy::hasImplThread() || m_useDoubleBuffering;
72 }
73
74 Canvas2DLayerChromium::~Canvas2DLayerChromium()
75 {
76     setTextureId(0);
77     if (m_context && m_useRateLimiter && layerTreeHost())
78         layerTreeHost()->stopRateLimiter(m_context.get());
79 }
80
81 bool Canvas2DLayerChromium::drawingIntoImplThreadTexture() const
82 {
83     return !m_useDoubleBuffering && CCProxy::hasImplThread() && layerTreeHost();
84 }
85
86 void Canvas2DLayerChromium::setTextureId(unsigned textureId)
87 {
88     if (m_backTextureId == textureId)
89         return;
90
91     if (m_backTextureId && drawingIntoImplThreadTexture()) {
92         // The impl tree may be referencing the old m_backTexture, which may
93         // soon be deleted. We must make sure the layer tree on the impl thread
94         // is not drawn until the next commit, which will re-synchronize the
95         // layer trees.
96         layerTreeHost()->acquireLayerTextures();
97     }
98     m_backTextureId = textureId;
99     setNeedsCommit();
100 }
101
102 void Canvas2DLayerChromium::setNeedsDisplayRect(const FloatRect& dirtyRect)
103 {
104     LayerChromium::setNeedsDisplayRect(dirtyRect);
105
106     if (m_useRateLimiter && layerTreeHost())
107         layerTreeHost()->startRateLimiter(m_context.get());
108 }
109
110 bool Canvas2DLayerChromium::drawsContent() const
111 {
112     return LayerChromium::drawsContent() && m_backTextureId && !m_size.isEmpty()
113         && !m_contextLost;
114 }
115
116 void Canvas2DLayerChromium::setCanvas(SkCanvas* canvas)
117 {
118     m_canvas = canvas;
119 }
120
121 void Canvas2DLayerChromium::update(CCTextureUpdater& updater, const CCOcclusionTracker*)
122 {
123     TRACE_EVENT0("cc", "Canvas2DLayerChromium::update");
124     if (!drawsContent())
125         return;
126
127     if (m_useDoubleBuffering && layerTreeHost()) {
128         TextureManager* textureManager = layerTreeHost()->contentsTextureManager();
129         if (m_frontTexture)
130             m_frontTexture->setTextureManager(textureManager);
131         else
132             m_frontTexture = ManagedTexture::create(textureManager);
133         if (m_frontTexture->reserve(m_size, GraphicsContext3D::RGBA))
134             updater.appendManagedCopy(m_backTextureId, m_frontTexture.get(), m_size);
135     }
136
137     if (!needsDisplay())
138         return;
139
140     m_needsDisplay = false;
141
142     bool success = m_context->makeContextCurrent();
143     ASSERT_UNUSED(success, success);
144
145     m_contextLost = m_context->getExtensions()->getGraphicsResetStatusARB() != GraphicsContext3D::NO_ERROR;
146     if (m_contextLost)
147         return;
148
149     if (m_canvas) {
150         TRACE_EVENT0("cc", "SkCanvas::flush");
151         m_canvas->flush();
152     }
153
154     TRACE_EVENT0("cc", "GraphicsContext3D::flush");
155     m_context->flush();
156 }
157
158 void Canvas2DLayerChromium::layerWillDraw(WillDrawCondition condition) const
159 {
160     if (drawingIntoImplThreadTexture()) {
161         if (condition == WillDrawUnconditionally || m_deferralMode == NonDeferred)
162             layerTreeHost()->acquireLayerTextures();
163     }
164 }
165
166
167 void Canvas2DLayerChromium::pushPropertiesTo(CCLayerImpl* layer)
168 {
169     CanvasLayerChromium::pushPropertiesTo(layer);
170
171     CCTextureLayerImpl* textureLayer = static_cast<CCTextureLayerImpl*>(layer);
172     if (m_useDoubleBuffering) {
173         if (m_frontTexture && m_frontTexture->isValid(m_size, GraphicsContext3D::RGBA))
174             textureLayer->setTextureId(m_frontTexture->textureId());
175         else
176             textureLayer->setTextureId(0);
177     } else
178         textureLayer->setTextureId(m_backTextureId);
179 }
180
181 }
182
183 #endif // USE(ACCELERATED_COMPOSITING)