Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(26)

Side by Side Diff: Source/WebCore/platform/graphics/surfaces/glx/GraphicsSurfaceGLX.cpp

Issue 13529026: Removing a bunch of unused platform code. (Closed) Base URL: svn://svn.chromium.org/blink/trunk
Patch Set: Fix whitespace and compiler error on Mac. Created 7 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
1 /*
2 Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies)
3 Copyright (C) 2013 Intel Corporation.
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 "GraphicsSurface.h"
23
24 #if USE(GRAPHICS_SURFACE)
25
26 #include "NotImplemented.h"
27 #include "TextureMapperGL.h"
28
29 #if PLATFORM(QT)
30 // Qt headers must be included before glx headers.
31 #include <QGuiApplication>
32 #include <QOpenGLContext>
33 #include <qpa/qplatformnativeinterface.h>
34 #include <GL/glext.h>
35 #include <GL/glx.h>
36 #else
37 #include <opengl/GLDefs.h>
38 #endif
39
40 #include "GLXConfigSelector.h"
41
42 namespace WebCore {
43
44 static PFNGLXBINDTEXIMAGEEXTPROC pGlXBindTexImageEXT = 0;
45 static PFNGLXRELEASETEXIMAGEEXTPROC pGlXReleaseTexImageEXT = 0;
46 static PFNGLBINDFRAMEBUFFERPROC pGlBindFramebuffer = 0;
47 static PFNGLBLITFRAMEBUFFERPROC pGlBlitFramebuffer = 0;
48 static PFNGLGENFRAMEBUFFERSPROC pGlGenFramebuffers = 0;
49 static PFNGLDELETEFRAMEBUFFERSPROC pGlDeleteFramebuffers = 0;
50 static PFNGLFRAMEBUFFERTEXTURE2DPROC pGlFramebufferTexture2D = 0;
51
52 static int glxAttributes[] = {
53 GLX_TEXTURE_FORMAT_EXT,
54 GLX_TEXTURE_FORMAT_RGBA_EXT,
55 GLX_TEXTURE_TARGET_EXT,
56 GLX_TEXTURE_2D_EXT,
57 0
58 };
59
60 static bool isMesaGLX()
61 {
62 static bool isMesa = !!strstr(glXGetClientString(X11Helper::nativeDisplay(), GLX_VENDOR), "Mesa");
63 return isMesa;
64 }
65
66 struct GraphicsSurfacePrivate {
67 GraphicsSurfacePrivate(const PlatformGraphicsContext3D shareContext = 0)
68 : m_xPixmap(0)
69 , m_glxPixmap(0)
70 , m_surface(0)
71 , m_glxSurface(0)
72 , m_glContext(0)
73 , m_detachedContext(0)
74 , m_detachedSurface(0)
75 , m_isReceiver(false)
76 , m_texture(0)
77 {
78 GLXContext shareContextObject = 0;
79
80 #if PLATFORM(QT)
81 if (shareContext) {
82 QPlatformNativeInterface* nativeInterface = QGuiApplication::platfor mNativeInterface();
83 shareContextObject = static_cast<GLXContext>(nativeInterface->native ResourceForContext(QByteArrayLiteral("glxcontext"), shareContext));
84 if (!shareContextObject)
85 return;
86 }
87 #else
88 UNUSED_PARAM(shareContext);
89 #endif
90
91 GLPlatformSurface::SurfaceAttributes sharedSurfaceAttributes = GLPlatfor mSurface::DoubleBuffered |
92 GLPlatformSurface::SupportAlpha;
93 m_configSelector = adoptPtr(new GLXConfigSelector(sharedSurfaceAttribute s));
94
95 if (!m_configSelector->surfaceContextConfig()) {
96 clear();
97 return;
98 }
99
100 // Create a GLX context for OpenGL rendering
101 m_glContext = glXCreateNewContext(display(), m_configSelector->surfaceCo ntextConfig(), GLX_RGBA_TYPE, shareContextObject, true);
102 }
103
104 GraphicsSurfacePrivate(uint32_t winId)
105 : m_xPixmap(0)
106 , m_glxPixmap(0)
107 , m_surface(winId)
108 , m_glxSurface(0)
109 , m_glContext(0)
110 , m_detachedContext(0)
111 , m_detachedSurface(0)
112 , m_isReceiver(true)
113 , m_texture(0)
114 {
115 }
116
117 ~GraphicsSurfacePrivate()
118 {
119 clear();
120 }
121
122 uint32_t createSurface(const IntSize& size)
123 {
124 if (!display() || !m_configSelector)
125 return 0;
126
127 GLXFBConfig config = m_configSelector->surfaceContextConfig();
128 OwnPtrX11<XVisualInfo> visInfo(m_configSelector->visualInfo(config));
129
130 if (!visInfo.get()) {
131 clear();
132 return 0;
133 }
134
135 X11Helper::createOffScreenWindow(&m_surface, *visInfo.get(), size);
136
137 if (!m_surface) {
138 clear();
139 return 0;
140 }
141
142 m_glxSurface = glXCreateWindow(display(), config, m_surface, 0);
143 return m_surface;
144 }
145
146 void createPixmap(uint32_t winId)
147 {
148 XWindowAttributes attr;
149 if (!XGetWindowAttributes(display(), winId, &attr))
150 return;
151
152 // Ensure that the window is mapped.
153 if (attr.map_state == IsUnmapped || attr.map_state == IsUnviewable)
154 return;
155
156 ScopedXPixmapCreationErrorHandler handler;
157 m_size = IntSize(attr.width, attr.height);
158
159 XRenderPictFormat* format = XRenderFindVisualFormat(display(), attr.visu al);
160 bool hasAlpha = (format->type == PictTypeDirect && format->direct.alphaM ask);
161 m_xPixmap = XCompositeNameWindowPixmap(display(), winId);
162 glxAttributes[1] = (format->depth == 32 && hasAlpha) ? GLX_TEXTURE_FORMA T_RGBA_EXT : GLX_TEXTURE_FORMAT_RGB_EXT;
163
164 GLPlatformSurface::SurfaceAttributes sharedSurfaceAttributes = GLPlatfor mSurface::Default;
165 if (hasAlpha)
166 sharedSurfaceAttributes = GLPlatformSurface::SupportAlpha;
167
168 if (!m_configSelector)
169 m_configSelector = adoptPtr(new GLXConfigSelector(sharedSurfaceAttri butes));
170
171 m_glxPixmap = glXCreatePixmap(display(), m_configSelector->surfaceClient Config(format->depth, XVisualIDFromVisual(attr.visual)), m_xPixmap, glxAttribute s);
172
173 if (!handler.isValidOperation())
174 clear();
175 else {
176 uint inverted = 0;
177 glXQueryDrawable(display(), m_glxPixmap, GLX_Y_INVERTED_EXT, &invert ed);
178 m_flags = !!inverted ? TextureMapperGL::ShouldFlipTexture : 0;
179
180 if (hasAlpha)
181 m_flags |= TextureMapperGL::ShouldBlend;
182 }
183 }
184
185 void makeCurrent()
186 {
187 m_detachedContext = glXGetCurrentContext();
188 m_detachedSurface = glXGetCurrentDrawable();
189 if (m_surface && m_glContext)
190 glXMakeCurrent(display(), m_surface, m_glContext);
191 }
192
193 void doneCurrent()
194 {
195 if (m_detachedContext)
196 glXMakeCurrent(display(), m_detachedSurface, m_detachedContext);
197 m_detachedContext = 0;
198 }
199
200 void swapBuffers()
201 {
202 if (isReceiver()) {
203 if (isMesaGLX() && textureID()) {
204 glBindTexture(GL_TEXTURE_2D, textureID());
205 // Mesa doesn't re-bind texture to the front buffer on glXSwapBu fer
206 // Manually release previous lock and rebind texture to surface to ensure frame updates.
207 pGlXReleaseTexImageEXT(display(), glxPixmap(), GLX_FRONT_EXT);
208 pGlXBindTexImageEXT(display(), glxPixmap(), GLX_FRONT_EXT, 0);
209 }
210
211 return;
212 }
213
214 GLXContext glContext = glXGetCurrentContext();
215
216 if (m_surface && glContext) {
217 GLint oldFBO;
218 glGetIntegerv(GL_FRAMEBUFFER_BINDING, &oldFBO);
219 pGlBindFramebuffer(GL_FRAMEBUFFER, 0);
220 glXSwapBuffers(display(), m_surface);
221 pGlBindFramebuffer(GL_FRAMEBUFFER, oldFBO);
222 }
223 }
224
225 void copyFromTexture(uint32_t texture, const IntRect& sourceRect)
226 {
227 makeCurrent();
228 int x = sourceRect.x();
229 int y = sourceRect.y();
230 int width = sourceRect.width();
231 int height = sourceRect.height();
232
233 glPushAttrib(GL_ALL_ATTRIB_BITS);
234 GLint previousFBO;
235 glGetIntegerv(GL_FRAMEBUFFER_BINDING, &previousFBO);
236
237 GLuint originFBO;
238 pGlGenFramebuffers(1, &originFBO);
239 pGlBindFramebuffer(GL_READ_FRAMEBUFFER, originFBO);
240 glBindTexture(GL_TEXTURE_2D, texture);
241 pGlFramebufferTexture2D(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TE XTURE_2D, texture, 0);
242
243 pGlBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
244 pGlBlitFramebuffer(x, y, width, height, x, y, width, height, GL_COLOR_BU FFER_BIT, GL_LINEAR);
245
246 pGlFramebufferTexture2D(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TE XTURE_2D, 0, 0);
247 glBindTexture(GL_TEXTURE_2D, 0);
248 pGlBindFramebuffer(GL_FRAMEBUFFER, previousFBO);
249 pGlDeleteFramebuffers(1, &originFBO);
250
251 glPopAttrib();
252
253 swapBuffers();
254 doneCurrent();
255 }
256
257 Display* display() const { return X11Helper::nativeDisplay(); }
258
259 GLXPixmap glxPixmap() const
260 {
261 if (!m_glxPixmap && m_surface)
262 const_cast<GraphicsSurfacePrivate*>(this)->createPixmap(m_surface);
263 return m_glxPixmap;
264 }
265
266 IntSize size() const
267 {
268 if (m_size.isEmpty()) {
269 XWindowAttributes attr;
270 if (XGetWindowAttributes(display(), m_surface, &attr))
271 const_cast<GraphicsSurfacePrivate*>(this)->m_size = IntSize(attr .width, attr.height);
272 }
273 return m_size;
274 }
275
276 bool isReceiver() const { return m_isReceiver; }
277
278 TextureMapperGL::Flags flags() const { return m_flags; }
279
280 Window surface() const { return m_surface; }
281
282 GLuint textureID() const
283 {
284 if (m_texture)
285 return m_texture;
286
287 GLXPixmap pixmap = glxPixmap();
288 if (!pixmap)
289 return 0;
290
291 GLuint texture;
292 glGenTextures(1, &texture);
293 glBindTexture(GL_TEXTURE_2D, texture);
294 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
295 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
296 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
297 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
298 pGlXBindTexImageEXT(display(), pixmap, GLX_FRONT_EXT, 0);
299 const_cast<GraphicsSurfacePrivate*>(this)->m_texture = texture;
300
301 return texture;
302 }
303 private:
304 void clear()
305 {
306 if (m_texture) {
307 pGlXReleaseTexImageEXT(display(), glxPixmap(), GLX_FRONT_EXT);
308 glDeleteTextures(1, &m_texture);
309 }
310
311 if (m_glxPixmap) {
312 glXDestroyPixmap(display(), m_glxPixmap);
313 m_glxPixmap = 0;
314 }
315
316 if (m_xPixmap) {
317 XFreePixmap(display(), m_xPixmap);
318 m_xPixmap = 0;
319 }
320
321 // Client doesn't own the window. Delete surface only on writing side.
322 if (!m_isReceiver && m_surface) {
323 XDestroyWindow(display(), m_surface);
324 m_surface = 0;
325 }
326
327 if (m_glContext) {
328 glXDestroyContext(display(), m_glContext);
329 m_glContext = 0;
330 }
331
332 if (m_configSelector)
333 m_configSelector = nullptr;
334 }
335
336 IntSize m_size;
337 Pixmap m_xPixmap;
338 GLXPixmap m_glxPixmap;
339 uint32_t m_surface;
340 Window m_glxSurface;
341 GLXContext m_glContext;
342 GLXContext m_detachedContext;
343 GLXDrawable m_detachedSurface;
344 OwnPtr<GLXConfigSelector> m_configSelector;
345 bool m_isReceiver;
346 TextureMapperGL::Flags m_flags;
347 GLuint m_texture;
348 };
349
350 static bool resolveGLMethods()
351 {
352 static bool resolved = false;
353 if (resolved)
354 return true;
355 pGlXBindTexImageEXT = reinterpret_cast<PFNGLXBINDTEXIMAGEEXTPROC>(glXGetProc Address(reinterpret_cast<const GLubyte*>("glXBindTexImageEXT")));
356 pGlXReleaseTexImageEXT = reinterpret_cast<PFNGLXRELEASETEXIMAGEEXTPROC>(glXG etProcAddress(reinterpret_cast<const GLubyte*>("glXReleaseTexImageEXT")));
357 pGlBindFramebuffer = reinterpret_cast<PFNGLBINDFRAMEBUFFERPROC>(glXGetProcAd dress(reinterpret_cast<const GLubyte*>("glBindFramebuffer")));
358 pGlBlitFramebuffer = reinterpret_cast<PFNGLBLITFRAMEBUFFERPROC>(glXGetProcAd dress(reinterpret_cast<const GLubyte*>("glBlitFramebuffer")));
359
360 pGlGenFramebuffers = reinterpret_cast<PFNGLGENFRAMEBUFFERSPROC>(glXGetProcAd dress(reinterpret_cast<const GLubyte*>("glGenFramebuffers")));
361 pGlDeleteFramebuffers = reinterpret_cast<PFNGLDELETEFRAMEBUFFERSPROC>(glXGet ProcAddress(reinterpret_cast<const GLubyte*>("glDeleteFramebuffers")));
362 pGlFramebufferTexture2D = reinterpret_cast<PFNGLFRAMEBUFFERTEXTURE2DPROC>(gl XGetProcAddress(reinterpret_cast<const GLubyte*>("glFramebufferTexture2D")));
363 resolved = pGlBlitFramebuffer && pGlBindFramebuffer && pGlXBindTexImageEXT & & pGlXReleaseTexImageEXT;
364
365 return resolved;
366 }
367
368 GraphicsSurfaceToken GraphicsSurface::platformExport()
369 {
370 return GraphicsSurfaceToken(m_private->surface());
371 }
372
373 uint32_t GraphicsSurface::platformGetTextureID()
374 {
375 return m_private->textureID();
376 }
377
378 void GraphicsSurface::platformCopyToGLTexture(uint32_t /*target*/, uint32_t /*id */, const IntRect& /*targetRect*/, const IntPoint& /*offset*/)
379 {
380 // This is not supported by GLX/Xcomposite.
381 }
382
383 void GraphicsSurface::platformCopyFromTexture(uint32_t texture, const IntRect& s ourceRect)
384 {
385 m_private->copyFromTexture(texture, sourceRect);
386 }
387
388 void GraphicsSurface::platformPaintToTextureMapper(TextureMapper* textureMapper, const FloatRect& targetRect, const TransformationMatrix& transform, float opaci ty)
389 {
390 IntSize size = m_private->size();
391 if (size.isEmpty())
392 return;
393 uint32_t texture = platformGetTextureID();
394 if (!texture)
395 return;
396
397 FloatRect rectOnContents(FloatPoint::zero(), size);
398 TransformationMatrix adjustedTransform = transform;
399 adjustedTransform.multiply(TransformationMatrix::rectToRect(rectOnContents, targetRect));
400 static_cast<TextureMapperGL*>(textureMapper)->drawTexture(texture, m_private ->flags(), size, rectOnContents, adjustedTransform, opacity);
401 }
402
403 uint32_t GraphicsSurface::platformFrontBuffer() const
404 {
405 return 0;
406 }
407
408 uint32_t GraphicsSurface::platformSwapBuffers()
409 {
410 m_private->swapBuffers();
411 return 0;
412 }
413
414 IntSize GraphicsSurface::platformSize() const
415 {
416 return m_private->size();
417 }
418
419 PassRefPtr<GraphicsSurface> GraphicsSurface::platformCreate(const IntSize& size, Flags flags, const PlatformGraphicsContext3D shareContext)
420 {
421 // X11 does not support CopyToTexture, so we do not create a GraphicsSurface if this is requested.
422 // GraphicsSurfaceGLX uses an XWindow as native surface. This one always has a front and a back buffer.
423 // Therefore single buffered GraphicsSurfaces are not supported.
424 if (flags & SupportsCopyToTexture || flags & SupportsSingleBuffered)
425 return PassRefPtr<GraphicsSurface>();
426
427 RefPtr<GraphicsSurface> surface = adoptRef(new GraphicsSurface(size, flags)) ;
428
429 surface->m_private = new GraphicsSurfacePrivate(shareContext);
430 if (!resolveGLMethods())
431 return PassRefPtr<GraphicsSurface>();
432
433 surface->m_private->createSurface(size);
434
435 return surface;
436 }
437
438 PassRefPtr<GraphicsSurface> GraphicsSurface::platformImport(const IntSize& size, Flags flags, const GraphicsSurfaceToken& token)
439 {
440 // X11 does not support CopyToTexture, so we do not create a GraphicsSurface if this is requested.
441 // GraphicsSurfaceGLX uses an XWindow as native surface. This one always has a front and a back buffer.
442 // Therefore single buffered GraphicsSurfaces are not supported.
443 if (flags & SupportsCopyToTexture || flags & SupportsSingleBuffered)
444 return PassRefPtr<GraphicsSurface>();
445
446 RefPtr<GraphicsSurface> surface = adoptRef(new GraphicsSurface(size, flags)) ;
447
448 surface->m_private = new GraphicsSurfacePrivate(token.frontBufferHandle);
449 if (!resolveGLMethods())
450 return PassRefPtr<GraphicsSurface>();
451
452 return surface;
453 }
454
455 char* GraphicsSurface::platformLock(const IntRect&, int* /*outputStride*/, LockO ptions)
456 {
457 // GraphicsSurface is currently only being used for WebGL, which does not re quire this locking mechanism.
458 return 0;
459 }
460
461 void GraphicsSurface::platformUnlock()
462 {
463 // GraphicsSurface is currently only being used for WebGL, which does not re quire this locking mechanism.
464 }
465
466 void GraphicsSurface::platformDestroy()
467 {
468 delete m_private;
469 m_private = 0;
470 }
471
472 #if !PLATFORM(QT)
473 PassOwnPtr<GraphicsContext> GraphicsSurface::platformBeginPaint(const IntSize&, char*, int)
474 {
475 notImplemented();
476 return nullptr;
477 }
478
479 PassRefPtr<Image> GraphicsSurface::createReadOnlyImage(const IntRect&)
480 {
481 notImplemented();
482 return 0;
483 }
484 #endif
485 }
486 #endif
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698