2 * Copyright (C) 2012 Samsung Electronics. All rights reserved.
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
13 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
14 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
15 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
16 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
17 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
18 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
19 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
20 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
21 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 #if ENABLE(TIZEN_WEBKIT2_TILED_AC_SHARED_PLATFORM_SURFACE)
30 #include "SharedVideoPlatformSurfaceTizen.h"
31 #include "GraphicsContextPlatformPrivateCairo.h"
34 #include <cairo-xlib.h>
36 #include <EGL/eglext.h>
38 #include <X11/Xutil.h>
40 #if ENABLE(TIZEN_CANVAS_GRAPHICS_SURFACE)
41 #include "GraphicsSurface.h"
46 class VideoPlatformSurface {
48 static PassOwnPtr<VideoPlatformSurface> create(IntSize size);
49 ~VideoPlatformSurface();
51 int id() const { return m_platformSurface; }
52 void paintCurrentFrameInContext(GraphicsContext*, const IntRect&);
53 void copySurface(VideoPlatformSurface* other, SharedVideoPlatformSurfaceTizen::CopySurfaceType type);
54 bool hasAlpha() { return m_hasAlpha; }
57 VideoPlatformSurface();
59 bool initialize(IntSize size);
60 bool createPlatformSurface(IntSize size);
61 bool destroyPlatformSurface();
62 bool createPlatformSurfaceSurface();
63 bool destroyPlatformSurfaceSurface();
64 void clearPlatformSurfaceSurface();
66 int m_platformSurface;
68 Display* m_nativeDisplay;
70 EGLDisplay m_eglDisplay;
71 EGLContext m_eglContext;
72 EGLSurface m_eglSurface;
78 PassOwnPtr<VideoPlatformSurface> VideoPlatformSurface::create(IntSize size)
80 OwnPtr<VideoPlatformSurface> videoPlatformSurface = adoptPtr(new VideoPlatformSurface());
81 if (!videoPlatformSurface->initialize(size))
83 return videoPlatformSurface.release();
86 VideoPlatformSurface::VideoPlatformSurface()
87 : m_platformSurface(0)
90 , m_eglDisplay(EGL_NO_DISPLAY)
91 , m_eglContext(EGL_NO_CONTEXT)
92 , m_eglSurface(EGL_NO_SURFACE)
98 VideoPlatformSurface::~VideoPlatformSurface()
100 destroyPlatformSurfaceSurface();
101 destroyPlatformSurface();
104 void VideoPlatformSurface::paintCurrentFrameInContext(GraphicsContext* context, const IntRect& rect)
106 if (context->paintingDisabled())
109 if (m_size.isEmpty())
112 cairo_surface_t* surface = cairo_xlib_surface_create(m_nativeDisplay, m_platformSurface, DefaultVisual(m_nativeDisplay, DefaultScreen(m_nativeDisplay)), m_size.width(), m_size.height());
113 if (cairo_surface_status(surface) != CAIRO_STATUS_SUCCESS)
116 cairo_t* cr = context->platformContext()->cr();
119 cairo_set_source_surface(cr, surface, 0, 0);
123 cairo_surface_destroy(surface);
126 void VideoPlatformSurface::copySurface(VideoPlatformSurface* other, SharedVideoPlatformSurfaceTizen::CopySurfaceType type)
128 RefPtr<cairo_surface_t> surface = adoptRef(cairo_xlib_surface_create(m_nativeDisplay, m_platformSurface, DefaultVisual(m_nativeDisplay, DefaultScreen(m_nativeDisplay)), m_size.width(), m_size.height()));
129 RefPtr<cairo_t> context = adoptRef(cairo_create(surface.get()));
130 OwnPtr<WebCore::GraphicsContext> graphicsContext = adoptPtr(new GraphicsContext(context.get()));
132 float xScale = static_cast<float>(m_size.width()) / other->m_size.width();
133 float yScale = static_cast<float>(m_size.height()) / other->m_size.height();
137 if (xScale != yScale) {
139 case SharedVideoPlatformSurfaceTizen::FitToWidth:
140 yPosition = (m_size.height() - other->m_size.height() * xScale) / 2;
143 case SharedVideoPlatformSurfaceTizen::FitToHeight:
144 xPosition = (m_size.width() - other->m_size.width() * yScale) / 2;
149 graphicsContext->translate(xPosition, yPosition);
150 graphicsContext->scale(FloatSize(xScale, yScale));
151 other->paintCurrentFrameInContext(graphicsContext.get(), IntRect());
154 bool VideoPlatformSurface::initialize(IntSize size)
156 if (!createPlatformSurface(size))
159 if (!createPlatformSurfaceSurface())
164 clearPlatformSurfaceSurface();
169 bool VideoPlatformSurface::createPlatformSurface(IntSize size)
174 if (!m_nativeDisplay) {
176 m_nativeDisplay = (Display*)ecore_x_display_get();
180 m_nativeWindow = XCreateSimpleWindow(m_nativeDisplay, DefaultRootWindow(m_nativeDisplay), 0, 0, 1, 1, 0, BlackPixel(m_nativeDisplay, 0), WhitePixel(m_nativeDisplay, 0));
182 XSync(m_nativeDisplay, false);
184 int visualDepth = XDefaultDepth(m_nativeDisplay, DefaultScreen(m_nativeDisplay));
185 m_platformSurface = XCreatePixmap(m_nativeDisplay, m_nativeWindow, size.width(), size.height(), visualDepth);
187 XFlush(m_nativeDisplay);
189 #if USE(ACCELERATED_VIDEO_VAAPI)
190 m_hasAlpha = visualDepth == 32 ? true : false;
196 bool VideoPlatformSurface::destroyPlatformSurface()
198 if (m_platformSurface) {
199 XFreePixmap(m_nativeDisplay, m_platformSurface);
200 m_platformSurface = 0;
203 if (m_nativeWindow) {
204 XDestroyWindow(m_nativeDisplay, m_nativeWindow);
213 bool VideoPlatformSurface::createPlatformSurfaceSurface()
215 m_eglDisplay = eglGetDisplay(m_nativeDisplay);
216 if (m_eglDisplay == EGL_NO_DISPLAY)
220 if (eglInitialize(m_eglDisplay, &major, &minor) != EGL_TRUE)
224 EGLint configAttribs[32];
225 configAttribs[i++] = EGL_LEVEL;
226 configAttribs[i++] = 0;
227 // FIXME : Create PlatformSurface surface with RGB_565 when alpha is off. Graphics driver needs to be fixed first.
228 configAttribs[i++] = EGL_RED_SIZE;
229 configAttribs[i++] = 8;
230 configAttribs[i++] = EGL_GREEN_SIZE;
231 configAttribs[i++] = 8;
232 configAttribs[i++] = EGL_BLUE_SIZE;
233 configAttribs[i++] = 8;
234 configAttribs[i++] = EGL_ALPHA_SIZE;
235 configAttribs[i++] = m_hasAlpha ? 8 : 0;
236 configAttribs[i++] = EGL_MATCH_FORMAT_KHR;
237 configAttribs[i++] = EGL_FORMAT_RGBA_8888_EXACT_KHR;
238 configAttribs[i++] = EGL_SURFACE_TYPE;
239 configAttribs[i++] = EGL_PIXMAP_BIT | EGL_LOCK_SURFACE_BIT_KHR;
240 configAttribs[i++] = EGL_DEPTH_SIZE;
241 configAttribs[i++] = 0;
242 configAttribs[i++] = EGL_STENCIL_SIZE;
243 configAttribs[i++] = 0;
244 configAttribs[i++] = EGL_RENDERABLE_TYPE;
245 configAttribs[i++] = EGL_OPENGL_ES2_BIT;
246 configAttribs[i++] = EGL_NONE;
249 EGLint configCount = 0;
250 if (eglChooseConfig(m_eglDisplay, configAttribs, &config, 1, &configCount) != EGL_TRUE)
253 EGLint contextAttribs[] = { EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE };
254 m_eglContext = eglCreateContext(m_eglDisplay, config, EGL_NO_CONTEXT, contextAttribs);
255 if( m_eglContext == EGL_NO_CONTEXT)
258 m_eglSurface = eglCreatePixmapSurface(m_eglDisplay, config, m_platformSurface, NULL);
259 if (m_eglSurface == EGL_NO_SURFACE)
265 bool VideoPlatformSurface::destroyPlatformSurfaceSurface()
268 eglMakeCurrent(m_eglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
269 eglDestroySurface(m_eglDisplay, m_eglSurface);
270 m_eglSurface = EGL_NO_SURFACE;
274 eglMakeCurrent(m_eglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT);
275 eglDestroyContext(m_eglDisplay, m_eglContext);
276 m_eglContext = EGL_NO_CONTEXT;
279 m_eglDisplay = EGL_NO_DISPLAY;
284 void VideoPlatformSurface::clearPlatformSurfaceSurface()
286 RefPtr<cairo_surface_t> surface = adoptRef(cairo_xlib_surface_create(m_nativeDisplay, m_platformSurface, DefaultVisual(m_nativeDisplay, DefaultScreen(m_nativeDisplay)), m_size.width(), m_size.height()));
287 if (cairo_surface_status(surface.get()) != CAIRO_STATUS_SUCCESS)
290 RefPtr<cairo_t> cr = adoptRef(cairo_create(surface.get()));
291 cairo_set_source_surface(cr.get(), surface.get(), 0, 0);
292 int alphaValue = m_hasAlpha ? 1 : 0;
293 cairo_set_source_rgba(cr.get(), 0, 0, 0, alphaValue);
294 cairo_rectangle(cr.get(), 0, 0, m_size.width(), m_size.height());
295 cairo_fill(cr.get());
298 PassOwnPtr<SharedVideoPlatformSurfaceTizen> SharedVideoPlatformSurfaceTizen::create(IntSize size)
300 return adoptPtr(new SharedVideoPlatformSurfaceTizen(size));
303 SharedVideoPlatformSurfaceTizen::SharedVideoPlatformSurfaceTizen(IntSize size)
307 , m_platformSurface(VideoPlatformSurface::create(size))
309 if (!m_platformSurface)
312 registerDamageHandler();
313 m_flags = GraphicsSurface::Is2D | GraphicsSurface::UseLinearFilter;
314 if (m_platformSurface->hasAlpha())
315 m_flags |= GraphicsSurface::Alpha;
319 SharedVideoPlatformSurfaceTizen::~SharedVideoPlatformSurfaceTizen()
323 unregisterDamageHandler();
326 static Eina_Bool notifyDamageUpdated(void* data, int type, void* event)
328 SharedVideoPlatformSurfaceTizen* sharedVideoPlatformSurface = reinterpret_cast<SharedVideoPlatformSurfaceTizen*>(data);
329 sharedVideoPlatformSurface->platformSurfaceUpdated();
331 return ECORE_CALLBACK_PASS_ON;
334 int SharedVideoPlatformSurfaceTizen::id() const
336 return m_platformSurface ? m_platformSurface->id() : 0;
339 void SharedVideoPlatformSurfaceTizen::platformSurfaceUpdated()
342 m_listener->platformSurfaceUpdated();
345 void SharedVideoPlatformSurfaceTizen::setVideoPlatformSurfaceUpdateListener(VideoPlatformSurfaceUpdateListener* listener)
347 m_listener = listener;
350 void SharedVideoPlatformSurfaceTizen::paintCurrentFrameInContext(GraphicsContext* context, const IntRect& rect)
352 if (m_platformSurface)
353 m_platformSurface->paintCurrentFrameInContext(context, rect);
356 void SharedVideoPlatformSurfaceTizen::copySurface(SharedVideoPlatformSurfaceTizen* other, CopySurfaceType type)
358 if (m_platformSurface)
359 m_platformSurface->copySurface(other->m_platformSurface.get(), type);
362 void SharedVideoPlatformSurfaceTizen::registerDamageHandler()
364 if (!m_platformSurface)
367 m_damage = ecore_x_damage_new(m_platformSurface->id(), ECORE_X_DAMAGE_REPORT_RAW_RECTANGLES);
368 m_damageHandler = ecore_event_handler_add(ECORE_X_EVENT_DAMAGE_NOTIFY, notifyDamageUpdated, this);
371 void SharedVideoPlatformSurfaceTizen::unregisterDamageHandler()
374 ecore_x_damage_free(m_damage);
378 if (m_damageHandler) {
379 ecore_event_handler_del(m_damageHandler);
384 int SharedVideoPlatformSurfaceTizen::graphicsSurfaceFlags() const
391 #endif // ENABLE(TIZEN_WEBKIT2_TILED_AC_SHARED_PLATFORM_SURFACE)