Fix the issue that short black glitch when switching bandwidth.
[framework/web/webkit-efl.git] / Source / WebCore / platform / graphics / gstreamer / tizen / VideoLayerTizen.cpp
1 /*
2     Copyright (C) 2012 Samsung Electronics.
3
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.1 of the License, or (at your option) any later version.
8
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.
13
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.
18 */
19
20 #include "config.h"
21 #include "VideoLayerTizen.h"
22
23 #if ENABLE(TIZEN_ACCELERATED_COMPOSITING) && USE(TIZEN_TEXTURE_MAPPER)
24
25 #include "GraphicsContext.h"
26 #include "IntRect.h"
27 #include "RenderLayerBacking.h"
28
29 #if ENABLE(TIZEN_WEBKIT2_TILED_AC_SHARED_PLATFORM_SURFACE)
30 #include <gst/interfaces/xoverlay.h>
31 #include <gst/video/gstvideosink.h>
32 #include <gst/video/video.h>
33 #else
34 #include <cairo-xlib.h>
35 #include <X11/Xlib.h>
36 #include <X11/Xutil.h>
37 #endif // ENABLE(TIZEN_WEBKIT2_TILED_AC_SHARED_PLATFORM_SURFACE)
38
39 #if !ENABLE(TIZEN_WEBKIT2_TILED_AC_SHARED_PLATFORM_SURFACE)
40 static Display* g_nativeDisplay = 0;
41 static int g_nativeWindow = 0;
42 #endif
43
44 namespace WebCore {
45
46 #if USE(ACCELERATED_VIDEO_VAAPI)
47     void setVaapiEnv()
48     {
49         static bool envSet = false;
50         if (!envSet) {
51             envSet = true;
52             setenv("PSB_VIDEO_CTEXTURE", "1", true);
53         }
54     }
55 #endif
56
57 VideoLayerTizen::VideoLayerTizen(HTMLMediaElement* media)
58     : m_media(media)
59 #if ENABLE(TIZEN_WEBKIT2_TILED_AC_SHARED_PLATFORM_SURFACE)
60     , m_videoSink(0)
61 #else
62     , m_platformSurfaceID(0)
63 #endif // ENABLE(TIZEN_WEBKIT2_TILED_AC_SHARED_PLATFORM_SURFACE)
64 {
65 #if !ENABLE(TIZEN_WEBKIT2_TILED_AC_SHARED_PLATFORM_SURFACE)
66     if (!g_nativeDisplay)
67            g_nativeDisplay = XOpenDisplay(0);
68
69        if (!g_nativeDisplay)
70            return;
71
72        g_nativeWindow = XCreateSimpleWindow(g_nativeDisplay, XDefaultRootWindow(g_nativeDisplay),
73                                0, 0, 1, 1, 0,
74                                BlackPixel(g_nativeDisplay, 0), WhitePixel(g_nativeDisplay, 0));
75        XFlush(g_nativeDisplay);
76 #endif
77 }
78
79 VideoLayerTizen::~VideoLayerTizen()
80 {
81     syncLayer(0);
82
83 #if ENABLE(TIZEN_WEBKIT2_TILED_AC_SHARED_PLATFORM_SURFACE)
84     if (m_platformSurface)
85         m_platformSurface.clear();
86
87     if (m_platformSurfaceToBeRemoved)
88         m_platformSurfaceToBeRemoved.clear();
89
90     m_videoSink = 0;
91 #else
92     if (m_platformSurfaceID) {
93         XFreePixmap(g_nativeDisplay, m_platformSurfaceID);
94         m_platformSurfaceID = 0;
95     }
96     if (g_nativeWindow) {
97         XDestroyWindow(g_nativeDisplay, g_nativeWindow);
98         g_nativeWindow = 0;
99     }
100 #endif // ENABLE(TIZEN_WEBKIT2_TILED_AC_SHARED_PLATFORM_SURFACE)
101 }
102
103 PlatformLayer* VideoLayerTizen::platformLayer() const
104 {
105     return const_cast<TextureMapperPlatformLayer*>(static_cast<const TextureMapperPlatformLayer*>(this));
106 }
107
108 void VideoLayerTizen::syncLayer(VideoLayerTizen* layer)
109 {
110     RenderBox* renderBox = m_media->renderBox();
111     if (renderBox && renderBox->hasAcceleratedCompositing()) {
112         RenderLayer* renderLayer = renderBox->layer();
113         if (renderLayer && renderLayer->isComposited()) {
114             GraphicsLayer* graphicsLayer = renderLayer->backing()->graphicsLayer();
115             if (graphicsLayer)
116                 graphicsLayer->setContentsToMedia(layer);
117         }
118     }
119 }
120
121 #if ENABLE(TIZEN_WEBKIT2_TILED_AC_SHARED_PLATFORM_SURFACE)
122 static gboolean platformSurfaceUpdateTimeoutCallback(VideoLayerTizen* layer)
123 {
124     layer->notifySyncRequired();
125     return FALSE;
126 }
127
128 bool VideoLayerTizen::swapPlatformSurfaces()
129 {
130     return true;
131 }
132
133 void VideoLayerTizen::freePlatformSurface(int id)
134 {
135     if (m_platformSurfaceToBeRemoved)
136         m_platformSurfaceToBeRemoved.clear();
137 }
138
139 void VideoLayerTizen::platformSurfaceUpdated()
140 {
141     notifySyncRequired();
142 }
143
144 GstElement* VideoLayerTizen::createVideoSink()
145 {
146 #if !USE(ACCELERATED_VIDEO_VAAPI)
147     GstElement* videoSink = gst_element_factory_make("xvimagesink", "xvimagesink");
148     g_object_set(videoSink, "rotate", 0, NULL);
149 #else
150     setVaapiEnv();
151     GstElement* videoSink = gst_element_factory_make("vaapisink", "vaapisink");
152     g_object_set(videoSink, "is-pixmap", 1, NULL);
153 #endif
154
155     m_videoSink = videoSink;
156
157     return videoSink;
158 }
159
160 void VideoLayerTizen::notifySyncRequired()
161 {
162     if (!m_platformSurface)
163         return;
164
165     syncLayer(this);
166 }
167
168 void VideoLayerTizen::setOverlay(IntSize size)
169 {
170     if (size.isEmpty())
171         return;
172
173     if (!m_videoSink)
174         return;
175
176     if (m_platformSurface)
177         m_platformSurfaceToBeRemoved = m_platformSurface.release();
178
179     m_platformSurface = SharedVideoPlatformSurfaceTizen::create(size);
180     m_platformSurface->setVideoPlatformSurfaceUpdateListener(this);
181
182     if (m_platformSurfaceToBeRemoved)
183         m_platformSurface->copySurface(m_platformSurfaceToBeRemoved.get());
184
185     gst_x_overlay_set_window_handle(GST_X_OVERLAY(m_videoSink), m_platformSurface->id());
186 #if !USE(ACCELERATED_VIDEO_VAAPI)
187     g_object_set(m_videoSink, "rotate", 0, NULL);
188 #else
189     g_object_set(m_videoSink, "is-pixmap", 1, NULL);
190 #endif
191 }
192
193 void VideoLayerTizen::paintCurrentFrameInContext(GraphicsContext* context, const IntRect& rect)
194 {
195     if (m_platformSurface)
196         m_platformSurface->paintCurrentFrameInContext(context, rect);
197 }
198 #else
199
200 void VideoLayerTizen::paintVideoLayer(IntSize videoSize)
201 {
202     if (videoSize.isEmpty())
203         return;
204
205     if (m_videoSize != videoSize) {
206         m_videoSize = videoSize;
207
208         if (m_platformSurfaceID) {
209             XFreePixmap(g_nativeDisplay, m_platformSurfaceID);
210             m_platformSurfaceID = 0;
211         }
212         m_platformSurfaceID = XCreatePixmap(g_nativeDisplay, g_nativeWindow, m_videoSize.width(), m_videoSize.height(), DefaultDepth(g_nativeDisplay, DefaultScreen(g_nativeDisplay)));
213         XFlush(g_nativeDisplay);
214     }
215
216     RefPtr<cairo_surface_t> surface = adoptRef(cairo_xlib_surface_create(g_nativeDisplay, m_platformSurfaceID, DefaultVisual(g_nativeDisplay, DefaultScreen(g_nativeDisplay)), m_videoSize.width(), m_videoSize.height()));
217     if (cairo_surface_status(surface.get()) != CAIRO_STATUS_SUCCESS)
218        return;
219
220     RefPtr<cairo_t> cr = adoptRef(cairo_create(surface.get()));
221     OwnPtr<WebCore::GraphicsContext> context = adoptPtr(new GraphicsContext(cr.get()));
222     m_media->player()->paint(context.get(), IntRect(0, 0, m_videoSize.width(), m_videoSize.height()));
223     XFlush(g_nativeDisplay);
224
225     syncLayer(this);
226 }
227 #endif // ENABLE(TIZEN_WEBKIT2_TILED_AC_SHARED_PLATFORM_SURFACE)
228
229 #if USE(GRAPHICS_SURFACE) || ENABLE(TIZEN_CANVAS_GRAPHICS_SURFACE)
230 uint64_t VideoLayerTizen::graphicsSurfaceToken() const
231 {
232 #if ENABLE(TIZEN_WEBKIT2_TILED_AC_SHARED_PLATFORM_SURFACE)
233     return (m_platformSurface ? m_platformSurface->id() : 0);
234 #else
235     return m_platformSurfaceID;
236 #endif
237 }
238
239 uint32_t VideoLayerTizen::copyToGraphicsSurface()
240 {
241 #if ENABLE(TIZEN_WEBKIT2_TILED_AC_SHARED_PLATFORM_SURFACE)
242     return (m_platformSurface ? m_platformSurface->id() : 0);
243 #else
244     return m_platformSurfaceID;
245 #endif
246 }
247
248 int VideoLayerTizen::graphicsSurfaceFlags() const
249 {
250 #if ENABLE(TIZEN_WEBKIT2_TILED_AC_SHARED_PLATFORM_SURFACE)
251     return m_platformSurface ? m_platformSurface->graphicsSurfaceFlags() : GraphicsSurface::Is2D;
252 #else
253     return GraphicsSurface::Is2D;
254 #endif
255 }
256 #endif // USE(GRAPHICS_SURFACE) || ENABLE(TIZEN_CANVAS_GRAPHICS_SURFACE)
257
258 } // WebCore
259
260 #endif // ENABLE(TIZEN_ACCELERATED_COMPOSITING) && USE(TIZEN_TEXTURE_MAPPER)