[EFL][WebGL] Refactor GLPlatformSurface.
[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 #if USE(3D_GRAPHICS) || USE(ACCELERATED_COMPOSITING)
25
26 #include "HostWindow.h"
27 #include "NotImplemented.h"
28
29 namespace WebCore {
30
31 PassOwnPtr<GraphicsContext3DPrivate> GraphicsContext3DPrivate::create(GraphicsContext3D* context, HostWindow* hostWindow)
32 {
33     OwnPtr<GraphicsContext3DPrivate> platformLayer = adoptPtr(new GraphicsContext3DPrivate(context, hostWindow));
34
35     if (platformLayer && platformLayer->initialize())
36         return platformLayer.release();
37
38     return nullptr;
39 }
40
41 GraphicsContext3DPrivate::GraphicsContext3DPrivate(GraphicsContext3D* context, HostWindow* hostWindow)
42     : m_context(context)
43     , m_hostWindow(hostWindow)
44 {
45 }
46
47 bool GraphicsContext3DPrivate::initialize()
48 {
49     if (m_context->m_renderStyle == GraphicsContext3D::RenderDirectlyToHostWindow)
50         return false;
51
52     if (m_hostWindow && m_hostWindow->platformPageClient()) {
53         // FIXME: Implement this code path for WebKit1.
54         // Get Evas object from platformPageClient and set EvasGL related members.
55         return false;
56     }
57
58     m_offScreenContext = GLPlatformContext::createContext(m_context->m_renderStyle);
59     if (!m_offScreenContext)
60         return false;
61
62     if (m_context->m_renderStyle == GraphicsContext3D::RenderOffscreen) {
63         m_offScreenSurface = GLPlatformSurface::createOffScreenSurface();
64
65         if (!m_offScreenSurface)
66             return false;
67
68         if (!m_offScreenContext->initialize(m_offScreenSurface.get()))
69             return false;
70
71 #if USE(GRAPHICS_SURFACE)
72         if (!makeContextCurrent())
73             return false;
74
75         m_context->validateAttributes();
76         GLPlatformSurface::SurfaceAttributes sharedSurfaceAttributes = GLPlatformSurface::Default;
77         if (m_context->m_attrs.alpha)
78             sharedSurfaceAttributes = GLPlatformSurface::SupportAlpha;
79
80         m_offScreenContext->releaseCurrent();
81         m_sharedSurface = GLPlatformSurface::createTransportSurface(sharedSurfaceAttributes);
82         if (!m_sharedSurface)
83             return false;
84
85         m_sharedContext = GLPlatformContext::createContext(m_context->m_renderStyle);
86         if (!m_sharedContext)
87             return false;
88
89         if (!m_sharedContext->initialize(m_sharedSurface.get(), m_offScreenContext->handle()))
90             return false;
91
92         if (!makeSharedContextCurrent())
93             return false;
94
95         m_surfaceHandle = GraphicsSurfaceToken(m_sharedSurface->handle());
96 #endif
97     }
98
99     if (!makeContextCurrent())
100         return false;
101
102     return true;
103 }
104
105 GraphicsContext3DPrivate::~GraphicsContext3DPrivate()
106 {
107     releaseResources();
108 }
109
110 void GraphicsContext3DPrivate::releaseResources()
111 {
112     if (m_context->m_renderStyle == GraphicsContext3D::RenderToCurrentGLContext)
113         return;
114
115     // Release the current context and drawable only after destroying any associated gl resources.
116 #if USE(GRAPHICS_SURFACE)
117     if (m_sharedContext && m_sharedContext->handle() && m_sharedSurface)
118         makeSharedContextCurrent();
119
120     if (m_sharedSurface)
121         m_sharedSurface->destroy();
122
123     if (m_sharedContext) {
124         m_sharedContext->destroy();
125         m_sharedContext->releaseCurrent();
126     }
127 #endif
128     if (m_offScreenSurface)
129         m_offScreenSurface->destroy();
130
131     if (m_offScreenContext) {
132         m_offScreenContext->destroy();
133         m_offScreenContext->releaseCurrent();
134     }
135 }
136
137 bool GraphicsContext3DPrivate::createSurface(PageClientEfl*, bool)
138 {
139     notImplemented();
140     return false;
141 }
142
143 void GraphicsContext3DPrivate::setContextLostCallback(PassOwnPtr<GraphicsContext3D::ContextLostCallback> callBack)
144 {
145     m_contextLostCallback = callBack;
146 }
147
148 PlatformGraphicsContext3D GraphicsContext3DPrivate::platformGraphicsContext3D() const
149 {
150     return m_offScreenContext->handle();
151 }
152
153 bool GraphicsContext3DPrivate::makeContextCurrent() const
154 {
155     bool success = m_offScreenContext->makeCurrent(m_offScreenSurface.get());
156
157     if (!m_offScreenContext->isValid()) {
158         // FIXME: Restore context
159         if (m_contextLostCallback)
160             m_contextLostCallback->onContextLost();
161
162         return false;
163     }
164
165     return success;
166 }
167
168 bool GraphicsContext3DPrivate::prepareBuffer() const
169 {
170     if (!makeContextCurrent())
171         return false;
172
173     m_context->markLayerComposited();
174
175     if (m_context->m_attrs.antialias) {
176         bool enableScissorTest = false;
177         int width = m_context->m_currentWidth;
178         int height = m_context->m_currentHeight;
179         // We should copy the full buffer, and not respect the current scissor bounds.
180         // FIXME: It would be more efficient to track the state of the scissor test.
181         if (m_context->isEnabled(GraphicsContext3D::SCISSOR_TEST)) {
182             enableScissorTest = true;
183             m_context->disable(GraphicsContext3D::SCISSOR_TEST);
184         }
185
186         glBindFramebuffer(Extensions3D::READ_FRAMEBUFFER, m_context->m_multisampleFBO);
187         glBindFramebuffer(Extensions3D::DRAW_FRAMEBUFFER, m_context->m_fbo);
188
189         // Use NEAREST as no scale is performed during the blit.
190         m_context->getExtensions()->blitFramebuffer(0, 0, width, height, 0, 0, width, height, GraphicsContext3D::COLOR_BUFFER_BIT, GraphicsContext3D::NEAREST);
191
192         if (enableScissorTest)
193             m_context->enable(GraphicsContext3D::SCISSOR_TEST);
194     }
195
196     return true;
197 }
198
199 #if USE(TEXTURE_MAPPER_GL)
200 void GraphicsContext3DPrivate::paintToTextureMapper(TextureMapper*, const FloatRect& /* target */, const TransformationMatrix&, float /* opacity */, BitmapTexture* /* mask */)
201 {
202     notImplemented();
203 }
204 #endif
205
206 #if USE(GRAPHICS_SURFACE)
207 bool GraphicsContext3DPrivate::makeSharedContextCurrent() const
208 {
209     bool success = m_sharedContext->makeCurrent(m_sharedSurface.get());
210
211     if (!m_sharedContext->isValid()) {
212         // FIXME: Restore context
213         if (m_contextLostCallback)
214             m_contextLostCallback->onContextLost();
215
216         return false;
217     }
218
219     return success;
220 }
221
222 void GraphicsContext3DPrivate::didResizeCanvas(const IntSize& size)
223 {
224     m_size = size;
225
226     if (makeSharedContextCurrent())
227         m_sharedSurface->setGeometry(IntRect(0, 0, m_size.width(), m_size.height()));
228 }
229
230 uint32_t GraphicsContext3DPrivate::copyToGraphicsSurface()
231 {
232     if (m_context->m_layerComposited || !prepareBuffer() || !makeSharedContextCurrent())
233         return 0;
234
235     m_sharedSurface->updateContents(m_context->m_texture);
236     makeContextCurrent();
237     glBindFramebuffer(GL_FRAMEBUFFER,  m_context->m_boundFBO);
238     return 0;
239 }
240
241 GraphicsSurfaceToken GraphicsContext3DPrivate::graphicsSurfaceToken() const
242 {
243     return m_surfaceHandle;
244 }
245
246 IntSize GraphicsContext3DPrivate::platformLayerSize() const
247 {
248     return m_size;
249 }
250 #endif
251
252 } // namespace WebCore
253
254 #endif // USE(3D_GRAPHICS) || USE(ACCELERATED_COMPOSITING)