Replace WTF::move with WTFMove
[WebKit-https.git] / Source / WebCore / platform / graphics / efl / GraphicsContext3DPrivate.cpp
1 /*
2     Copyright (C) 2012 Samsung Electronics
3     Copyright (C) 2012 Intel Corporation. All rights reserved.
4
5     This library is free software; you can redistribute it and/or
6     modify it under the terms of the GNU Library General Public
7     License as published by the Free Software Foundation; either
8     version 2 of the License, or (at your option) any later version.
9
10     This library is distributed in the hope that it will be useful,
11     but WITHOUT ANY WARRANTY; without even the implied warranty of
12     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13     Library General Public License for more details.
14
15     You should have received a copy of the GNU Library General Public License
16     along with this library; see the file COPYING.LIB.  If not, write to
17     the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18     Boston, MA 02110-1301, USA.
19 */
20
21 #include "config.h"
22 #include "GraphicsContext3DPrivate.h"
23
24 #include "HostWindow.h"
25 #include "NotImplemented.h"
26
27 namespace WebCore {
28
29 std::unique_ptr<GraphicsContext3DPrivate> GraphicsContext3DPrivate::create(GraphicsContext3D* context, HostWindow* hostWindow)
30 {
31     std::unique_ptr<GraphicsContext3DPrivate> platformLayer = std::make_unique<GraphicsContext3DPrivate>(context, hostWindow);
32
33     if (platformLayer && platformLayer->initialize())
34         return platformLayer;
35
36     return nullptr;
37 }
38
39 GraphicsContext3DPrivate::GraphicsContext3DPrivate(GraphicsContext3D* context, HostWindow* hostWindow)
40     : m_context(context)
41     , m_hostWindow(hostWindow)
42 {
43 }
44
45 bool GraphicsContext3DPrivate::initialize()
46 {
47     if (m_context->m_renderStyle == GraphicsContext3D::RenderDirectlyToHostWindow)
48         return false;
49
50     if (m_hostWindow && m_hostWindow->platformPageClient()) {
51         // FIXME: Implement this code path for WebKit1.
52         // Get Evas object from platformPageClient and set EvasGL related members.
53         return false;
54     }
55
56     m_offScreenContext = GLPlatformContext::createContext(m_context->m_renderStyle);
57     if (!m_offScreenContext)
58         return false;
59
60     if (m_context->m_renderStyle == GraphicsContext3D::RenderOffscreen) {
61         m_offScreenSurface = GLPlatformSurface::createOffScreenSurface();
62
63         if (!m_offScreenSurface)
64             return false;
65
66         if (!m_offScreenContext->initialize(m_offScreenSurface.get()))
67             return false;
68
69         if (!makeContextCurrent())
70             return false;
71         m_surfaceOperation = CreateSurface;
72     }
73
74     return true;
75 }
76
77 GraphicsContext3DPrivate::~GraphicsContext3DPrivate()
78 {
79     releaseResources();
80 }
81
82 void GraphicsContext3DPrivate::releaseResources()
83 {
84     if (m_context->m_renderStyle == GraphicsContext3D::RenderToCurrentGLContext)
85         return;
86
87     // Release the current context and drawable only after destroying any associated gl resources.
88     if (m_previousGraphicsSurface)
89         m_previousGraphicsSurface = nullptr;
90
91     if (m_graphicsSurface)
92         m_graphicsSurface = nullptr;
93
94     m_surfaceHandle = GraphicsSurfaceToken();
95     if (m_offScreenSurface)
96         m_offScreenSurface->destroy();
97
98     if (m_offScreenContext) {
99         m_offScreenContext->destroy();
100         m_offScreenContext->releaseCurrent();
101     }
102 }
103
104 void GraphicsContext3DPrivate::setContextLostCallback(std::unique_ptr<GraphicsContext3D::ContextLostCallback> callBack)
105 {
106     m_contextLostCallback = WTFMove(callBack);
107 }
108
109 PlatformGraphicsContext3D GraphicsContext3DPrivate::platformGraphicsContext3D() const
110 {
111     return m_offScreenContext->handle();
112 }
113
114 bool GraphicsContext3DPrivate::makeContextCurrent() const
115 {
116     bool success = m_offScreenContext->makeCurrent(m_offScreenSurface.get());
117
118     if (!m_offScreenContext->isValid()) {
119         // FIXME: Restore context
120         if (m_contextLostCallback)
121             m_contextLostCallback->onContextLost();
122
123         return false;
124     }
125
126     return success;
127 }
128
129 bool GraphicsContext3DPrivate::prepareBuffer() const
130 {
131     if (!makeContextCurrent())
132         return false;
133
134     m_context->markLayerComposited();
135
136     if (m_context->m_attrs.antialias) {
137         bool enableScissorTest = false;
138         int width = m_context->m_currentWidth;
139         int height = m_context->m_currentHeight;
140         // We should copy the full buffer, and not respect the current scissor bounds.
141         // FIXME: It would be more efficient to track the state of the scissor test.
142         if (m_context->isEnabled(GraphicsContext3D::SCISSOR_TEST)) {
143             enableScissorTest = true;
144             m_context->disable(GraphicsContext3D::SCISSOR_TEST);
145         }
146
147         glBindFramebuffer(Extensions3D::READ_FRAMEBUFFER, m_context->m_multisampleFBO);
148         glBindFramebuffer(Extensions3D::DRAW_FRAMEBUFFER, m_context->m_fbo);
149
150         // Use NEAREST as no scale is performed during the blit.
151         m_context->getExtensions()->blitFramebuffer(0, 0, width, height, 0, 0, width, height, GraphicsContext3D::COLOR_BUFFER_BIT, GraphicsContext3D::NEAREST);
152
153         if (enableScissorTest)
154             m_context->enable(GraphicsContext3D::SCISSOR_TEST);
155
156         glBindFramebuffer(GL_FRAMEBUFFER, m_context->m_state.boundFBO);
157     }
158
159     return true;
160 }
161
162 void GraphicsContext3DPrivate::paintToTextureMapper(TextureMapper&, const FloatRect& /* target */, const TransformationMatrix&, float /* opacity */)
163 {
164     notImplemented();
165 }
166
167 void GraphicsContext3DPrivate::createGraphicsSurface()
168 {
169     static PendingSurfaceOperation pendingOperation = DeletePreviousSurface | Resize | CreateSurface;
170     if (!(m_surfaceOperation & pendingOperation))
171         return;
172
173     if (m_surfaceOperation & DeletePreviousSurface) {
174         m_previousGraphicsSurface = nullptr;
175         m_surfaceOperation &= ~DeletePreviousSurface;
176     }
177
178     if (!(m_surfaceOperation & pendingOperation))
179         return;
180
181     // Don't release current graphics surface until we have prepared surface
182     // with requested size. This is to avoid flashing during resize.
183     if (m_surfaceOperation & Resize) {
184         m_previousGraphicsSurface = m_graphicsSurface;
185         m_surfaceOperation &= ~Resize;
186         m_surfaceOperation |= DeletePreviousSurface;
187         m_size = IntSize(m_context->m_currentWidth, m_context->m_currentHeight);
188     } else
189         m_surfaceOperation &= ~CreateSurface;
190
191     m_targetRect = IntRect(IntPoint(), m_size);
192
193     if (m_size.isEmpty()) {
194         if (m_graphicsSurface) {
195             m_graphicsSurface = nullptr;
196             m_surfaceHandle = GraphicsSurfaceToken();
197             makeContextCurrent();
198         }
199
200         return;
201     }
202
203     m_offScreenContext->releaseCurrent();
204     GraphicsSurface::Flags flags = GraphicsSurface::SupportsTextureTarget | GraphicsSurface::SupportsSharing;
205
206     if (m_context->m_attrs.alpha)
207         flags |= GraphicsSurface::SupportsAlpha;
208
209     m_graphicsSurface = GraphicsSurface::create(m_size, flags, m_offScreenContext->handle());
210
211     if (!m_graphicsSurface)
212         m_surfaceHandle = GraphicsSurfaceToken();
213     else
214         m_surfaceHandle = GraphicsSurfaceToken(m_graphicsSurface->exportToken());
215
216     makeContextCurrent();
217 }
218
219 void GraphicsContext3DPrivate::didResizeCanvas(const IntSize& size)
220 {
221     if (m_surfaceOperation & CreateSurface) {
222         m_size = size;
223         createGraphicsSurface();
224         return;
225     }
226
227     m_surfaceOperation |= Resize;
228 }
229
230 uint32_t GraphicsContext3DPrivate::copyToGraphicsSurface()
231 {
232     createGraphicsSurface();
233
234     if (!m_graphicsSurface || m_context->m_layerComposited || !prepareBuffer())
235         return 0;
236
237     m_graphicsSurface->copyFromTexture(m_context->m_texture, m_targetRect);
238     makeContextCurrent();
239
240     return m_graphicsSurface->frontBuffer();
241 }
242
243 GraphicsSurfaceToken GraphicsContext3DPrivate::graphicsSurfaceToken() const
244 {
245     return m_surfaceHandle;
246 }
247
248 IntSize GraphicsContext3DPrivate::platformLayerSize() const
249 {
250     return m_size;
251 }
252
253 GraphicsSurface::Flags GraphicsContext3DPrivate::graphicsSurfaceFlags() const
254 {
255     if (m_graphicsSurface)
256         return m_graphicsSurface->flags();
257
258     return TextureMapperPlatformLayer::graphicsSurfaceFlags();
259 }
260
261 } // namespace WebCore