2 Copyright (C) 2012 Samsung Electronics
4 This library is free software; you can redistribute it and/or
5 modify it under the terms of the GNU Library General Public
6 License as published by the Free Software Foundation; either
7 version 2 of the License, or (at your option) any later version.
9 This library is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 Library General Public License for more details.
14 You should have received a copy of the GNU Library General Public License
15 along with this library; see the file COPYING.LIB. If not, write to
16 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
17 Boston, MA 02110-1301, USA.
21 #include "GraphicsSurface.h"
23 #if USE(GRAPHICS_SURFACE) || ENABLE(TIZEN_CANVAS_GRAPHICS_SURFACE)
24 #if !ENABLE(TIZEN_WEBKIT2_TILED_AC_SHARED_PLATFORM_SURFACE)
25 #include "TextureMapperGL.h"
27 #include "NotImplemented.h"
29 #include <GLES2/gl2.h>
31 #include <X11/Xutil.h>
32 #include <X11/extensions/XShm.h>
39 static Display *g_display = 0;
40 struct GraphicsSurfacePrivate {
41 GraphicsSurfacePrivate()
42 : m_textureIsYInverted(false)
45 , m_platformSurfaceID(0)
48 g_display = XOpenDisplay(0);
51 ~GraphicsSurfacePrivate()
54 XShmDetach(g_display, &(m_shmInfo));
55 XDestroyImage(m_xImage);
56 shmdt(m_shmInfo.shmaddr);
57 shmctl(m_shmInfo.shmid, IPC_RMID, 0);
62 uint32_t createSurface(const IntSize& size)
67 void createPlatformSurface(uint32_t winId)
71 void createImage(const IntSize& size, uint32_t platformSurfaceID)
73 m_platformSurfaceID = platformSurfaceID;
75 unsigned int w=0, h=0, bw=0, d=0;
79 fprintf(stderr, "Can not open display\n");
83 XGetGeometry(g_display, platformSurfaceID, &root_win, &x, &y, &w, &h, &bw, &d);
84 m_size = IntSize(w, h);
86 Screen* screen = DefaultScreenOfDisplay(g_display);
87 m_xImage = XShmCreateImage(g_display, DefaultVisualOfScreen(screen), 24, ZPixmap, NULL, &(m_shmInfo), m_size.width(), m_size.height());
89 fprintf(stderr, "Error creating the shared image\n");
92 m_shmInfo.shmid = shmget(IPC_PRIVATE, m_xImage->bytes_per_line * m_xImage->height, IPC_CREAT | 0666);
93 if (m_shmInfo.shmid == -1) {
94 XDestroyImage(m_xImage);
96 fprintf(stderr, "Error getting the shared image info\n");
99 m_shmInfo.readOnly = false;
100 m_shmInfo.shmaddr = (char*)shmat(m_shmInfo.shmid, 0, 0);
101 m_xImage->data = (char*)m_shmInfo.shmaddr;
103 if ((m_xImage->data == (char *)-1) || (!m_xImage->data)) {
104 shmdt(m_shmInfo.shmaddr);
105 shmctl(m_shmInfo.shmid, IPC_RMID, 0);
106 XDestroyImage(m_xImage);
111 XShmAttach(g_display, &m_shmInfo);
117 fprintf(stderr, "Can not open display\n");
124 XGrabServer(g_display);
125 if (!XShmGetImage(g_display, (Drawable)m_platformSurfaceID, m_xImage, 0, 0, 0xffffffff))
126 fprintf(stderr, "Error Getting ShmGetImage\n");
127 XUngrabServer(g_display);
128 XSync(g_display, false);
131 int totalBytes = m_size.width() * m_size.height() * 4;
132 for (int i = 0; i < totalBytes; i += 4)
133 std::swap(m_xImage->data[i], m_xImage->data[i + 2]);
136 void* xImageData() { return m_xImage ? m_xImage->data : 0; }
137 void swapBuffers() { }
138 IntSize size() const { return m_size; }
142 bool m_textureIsYInverted;
145 XShmSegmentInfo m_shmInfo;
146 int m_platformSurfaceID;
149 uint64_t GraphicsSurface::platformExport()
151 return m_platformSurface;
154 uint32_t GraphicsSurface::platformGetTextureID()
157 glGenTextures(1, &m_texture);
158 glBindTexture(GL_TEXTURE_2D, m_texture);
159 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
160 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
161 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
162 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
165 m_private->copyImage();
166 glBindTexture(GL_TEXTURE_2D, m_texture);
167 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, m_size.width(), m_size.height(), 0, GL_RGBA, GL_UNSIGNED_BYTE, m_private->xImageData());
172 void GraphicsSurface::platformPaintToTextureMapper(TextureMapper* textureMapper, const FloatRect& targetRect, const TransformationMatrix& transform, float opacity)
174 static_cast<TextureMapperGL*>(textureMapper)->drawTexture(platformGetTextureID(), 0, m_size, targetRect, transform, opacity);
177 PassRefPtr<GraphicsSurface> GraphicsSurface::platformCreate(const IntSize& size, Flags flags)
182 #if ENABLE(TIZEN_CANVAS_GRAPHICS_SURFACE)
183 PassRefPtr<GraphicsSurface> GraphicsSurface::platformCreate(uint64_t platformSurfaceID)
185 RefPtr<GraphicsSurface> surface = adoptRef(new GraphicsSurface(IntSize(), 0));
186 surface->m_private = new GraphicsSurfacePrivate();
187 surface->m_platformSurface = (uint64_t)platformSurfaceID;
191 PassRefPtr<GraphicsSurface> GraphicsSurface::platformImport(const IntSize& size, Flags flags, uint64_t token, Flags canvasFlags)
193 // X11 does not support CopyToTexture, so we do not create a GraphicsSurface if this is requested.
194 // GraphicsSurfaceGLX uses an XWindow as native surface. This one always has a front and a back buffer.
195 // Therefore single buffered GraphicsSurfaces are not supported.
196 RefPtr<GraphicsSurface> surface = adoptRef(new GraphicsSurface(size, flags));
197 surface->m_private = new GraphicsSurfacePrivate();
198 surface->m_platformSurface = token;
199 surface->m_canvasFlags = canvasFlags;
201 surface->m_private->createImage(IntSize(), token);
202 surface->m_size = surface->m_private->size();
210 PassRefPtr<GraphicsSurface> GraphicsSurface::platformImport(const IntSize& size, Flags flags, uint64_t token)
212 // X11 does not support CopyToTexture, so we do not create a GraphicsSurface if this is requested.
213 // GraphicsSurfaceGLX uses an XWindow as native surface. This one always has a front and a back buffer.
214 // Therefore single buffered GraphicsSurfaces are not supported.
215 RefPtr<GraphicsSurface> surface = adoptRef(new GraphicsSurface(size, flags));
216 surface->m_private = new GraphicsSurfacePrivate();
217 surface->m_platformSurface = token;
219 surface->m_private->createImage(IntSize(), token);
220 surface->m_size = surface->m_private->size();
225 void GraphicsSurface::platformDestroy()
228 glDeleteTextures(1, &m_texture);
238 void GraphicsSurface::platformCopyToGLTexture(uint32_t target, uint32_t id, const IntRect& targetRect, const IntPoint& offset)
240 // This is not supported by GLX/Xcomposite.
243 void GraphicsSurface::platformCopyFromFramebuffer(uint32_t originFbo, const IntRect& sourceRect)
247 uint32_t GraphicsSurface::platformFrontBuffer() const
252 uint32_t GraphicsSurface::platformSwapBuffers()
254 m_private->swapBuffers();
258 #if ENABLE(TIZEN_CANVAS_GRAPHICS_SURFACE)
259 uint32_t GraphicsSurface::platformSwapBuffers(uint32_t)
265 char* GraphicsSurface::platformLock(const IntRect& rect, int* outputStride, LockOptions lockOptions)
267 // GraphicsSurface is currently only being used for WebGL, which does not require this locking mechanism.
271 void GraphicsSurface::platformUnlock()
273 // GraphicsSurface is currently only being used for WebGL, which does not require this locking mechanism.
276 PassOwnPtr<GraphicsContext> GraphicsSurface::platformBeginPaint(const IntSize& size, char* bits, int stride)
282 PassRefPtr<Image> GraphicsSurface::createReadOnlyImage(const IntRect& rect)