Fix wl_buffer leak
[platform/framework/web/webkit-efl.git] / Source / WebCore / platform / graphics / surfaces / wayland / WaylandLockSurface.cpp
1 /*
2  * Copyright (C) 2013 Intel Corporation. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
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.
12  *
13  * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
14  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
15  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
17  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
18  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
19  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
20  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
21  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
22  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
23  * THE POSSIBILITY OF SUCH DAMAGE.
24  */
25
26 #include "config.h"
27 #include "WaylandLockSurface.h"
28
29 #include "WaylandBufferManager.h"
30
31 #if PLATFORM(WAYLAND)
32
33 namespace WebCore {
34
35 WaylandLockSurface::WaylandLockSurface(const IntSize& size, GLPlatformSurface::SurfaceAttributes attributes)
36     : GLPlatformSurface()
37     , m_attributes(attributes)
38     , m_drmHandle(0)
39     , m_buffer(0)
40 {
41     m_surface = WaylandDisplay::instance()->createSurface();
42
43     if (!m_surface) {
44         LOG_ERROR("Failed to create surface.");
45         destroy();
46         return;
47     }
48
49     m_bufferHandle = m_surface->handle();
50     m_rect = IntRect(0, 0, size.width(), size.height());
51     m_buffer = WaylandDisplay::instance()->createDrmBuffer(size.width(), size.height(), &m_drmHandle);
52     if (!m_drmHandle) {
53         LOG_ERROR("Failed to create DRM handle.");
54         destroy();
55         return;
56     }
57 }
58
59 WaylandLockSurface::~WaylandLockSurface()
60 {
61     m_bufferHandle = 0;
62 }
63
64 void WaylandLockSurface::swapBuffers()
65 {
66     if (m_surface->ensureFrameCallBackDone() == -1)
67         return;
68
69     m_surface->addFrameCallBack();
70 }
71
72 void WaylandLockSurface::destroy()
73 {
74     if (m_surface) {
75         m_surface->ensureFrameCallBackDone();
76         m_surface->deleteFrameCallBack();
77     }
78
79     wl_buffer_destroy(static_cast<wl_buffer*>(m_buffer));
80     m_buffer = 0;
81     WaylandDisplay::instance()->freeBO(m_drmHandle);
82     GLPlatformSurface::destroy();
83     m_surface = nullptr;
84     m_bufferHandle = 0;
85 }
86
87 void WaylandLockSurface::setGeometry(const IntRect& rect)
88 {
89     if (m_surface && rect != m_rect) {
90         m_rect = rect;
91         m_surface->ensureFrameCallBackDone();
92         wl_buffer_destroy(static_cast<wl_buffer*>(m_buffer));
93         WaylandDisplay::instance()->freeBO(m_drmHandle);
94         m_buffer = WaylandDisplay::instance()->createDrmBuffer(rect.width(), rect.height(), &m_drmHandle);
95         WaylandDisplay::instance()->syncDisplay();
96     }
97 }
98
99 bool WaylandLockSurface::lockSurface()
100 {
101     if (m_surface->ensureFrameCallBackDone() == -1)
102         return false;
103
104     return WaylandDisplay::instance()->lockSurface(m_drmHandle);
105 }
106
107 bool WaylandLockSurface::unlockSurface()
108 {
109     bool value = WaylandDisplay::instance()->unlockSurface(m_drmHandle);
110     if (!value)
111         return false;
112
113     m_surface->addFrameCallBack();
114     wl_surface_attach(m_surface->wlSurface(), static_cast<wl_buffer*>(m_buffer), 0, 0);
115     wl_surface_damage(m_surface->wlSurface(), 0, 0, m_rect.width(), m_rect.height());
116     wl_surface_commit(m_surface->wlSurface());
117     return value;
118 }
119
120 bool WaylandLockSurface::querySurface(int** value)
121 {
122     return WaylandDisplay::instance()->querySurface(m_drmHandle, value);
123 }
124
125 GLPlatformSurface::SurfaceAttributes WaylandLockSurface::attributes() const
126 {
127     return m_attributes;
128 }
129
130 }
131 #endif