1 // Copyright 2012 Intel Corporation
2 //
3 // All rights reserved.
4 //
5 // Redistribution and use in source and binary forms, with or without
6 // modification, are permitted provided that the following conditions are met:
7 //
8 // - Redistributions of source code must retain the above copyright notice, this
9 // list of conditions and the following disclaimer.
10 //
11 // - Redistributions in binary form must reproduce the above copyright notice,
12 // this list of conditions and the following disclaimer in the documentation
13 // and/or other materials provided with the distribution.
14 //
15 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
16 // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
18 // DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
19 // FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20 // DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
21 // SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
22 // CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
23 // OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
24 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25
26 #if WAFFLE_ANDROID_MAJOR_VERSION == 4 && \
27 WAFFLE_ANDROID_MINOR_VERSION >= 1 || \
28 WAFFLE_ANDROID_MAJOR_VERSION >= 5
29 # include <gui/Surface.h>
30 # include <gui/SurfaceComposerClient.h>
31 #elif WAFFLE_ANROID_MAJOR_VERSION >= 4 && \
32 WAFFLE_ANDROID_MINOR_VERSION == 0
33 # include <surfaceflinger/SurfaceComposerClient.h>
34 #else
35 # error "android >= 4.0 is required"
36 #endif
37
38 #include "droid_surfaceflingerlink.h"
39
40 #include "wcore_util.h"
41 #include "wcore_error.h"
42
43 using namespace android;
44
45 namespace waffle {
46
47 struct droid_surfaceflinger_container {
48 sp<SurfaceComposerClient> composer_client;
49 };
50
51 struct droid_ANativeWindow_container {
52 // it is important ANativeWindow* is the first element in this structure
53 ANativeWindow* native_window;
54 sp<SurfaceControl> surface_control;
55 sp<ANativeWindow> window;
56 };
57
58 const uint32_t droid_magic_surface_width = 32;
59 const uint32_t droid_magic_surface_height = 32;
60 const int32_t droid_magic_surface_z = 0x7FFFFFFF;
61
62 void droid_tear_down_surfaceflinger_link(
63 droid_surfaceflinger_container* pSFContainer);
64
65 droid_surfaceflinger_container*
droid_setup_surfaceflinger_link()66 droid_setup_surfaceflinger_link()
67 {
68 bool bRVal;
69 EGLint iRVal;
70 droid_surfaceflinger_container* pSFContainer;
71
72 pSFContainer = new droid_surfaceflinger_container;
73
74 if (pSFContainer == NULL)
75 goto error;
76
77 pSFContainer->composer_client = new SurfaceComposerClient;
78 iRVal = pSFContainer->composer_client->initCheck();
79 if (iRVal != NO_ERROR) {
80 wcore_errorf(WAFFLE_ERROR_UNKNOWN,
81 "android::SurfaceComposerClient->initCheck != NO_ERROR");
82 goto error;
83 }
84
85 return pSFContainer;
86 error:
87 droid_tear_down_surfaceflinger_link(pSFContainer);
88 return NULL;
89 }
90
91 droid_ANativeWindow_container*
droid_setup_surface(int width,int height,droid_surfaceflinger_container * pSFContainer)92 droid_setup_surface(
93 int width,
94 int height,
95 droid_surfaceflinger_container* pSFContainer)
96 {
97 bool bRVal;
98 EGLint iRVal;
99
100 droid_ANativeWindow_container* pANWContainer;
101
102 pANWContainer = new droid_ANativeWindow_container;
103
104 if (pANWContainer == NULL)
105 goto error;
106
107 // The signature of SurfaceComposerClient::createSurface() differs across
108 // Android versions.
109 #if WAFFLE_ANDROID_MAJOR_VERSION == 4 && \
110 WAFFLE_ANDROID_MINOR_VERSION >= 2 || \
111 WAFFLE_ANDROID_MAJOR_VERSION >= 5
112 pANWContainer->surface_control =
113 pSFContainer->composer_client->createSurface(
114 String8("Waffle Surface"),
115 droid_magic_surface_width, droid_magic_surface_height,
116 PIXEL_FORMAT_RGB_888, 0);
117 #else
118 pANWContainer->surface_control =
119 pSFContainer->composer_client->createSurface(
120 String8("Waffle Surface"), 0,
121 droid_magic_surface_width, droid_magic_surface_height,
122 PIXEL_FORMAT_RGB_888, 0);
123 #endif
124
125 if (pANWContainer->surface_control == NULL) {
126 wcore_errorf(WAFFLE_ERROR_UNKNOWN,
127 "Unable to get android::SurfaceControl");
128 delete pANWContainer;
129 goto error;
130 }
131
132 bRVal = pANWContainer->surface_control->isValid();
133 if (bRVal != true) {
134 wcore_errorf(WAFFLE_ERROR_UNKNOWN,
135 "Acquired android::SurfaceControl is invalid");
136 delete pANWContainer;
137 goto error;
138 }
139
140 pSFContainer->composer_client->openGlobalTransaction();
141 iRVal = pANWContainer->surface_control->setLayer(droid_magic_surface_z);
142 if (iRVal != NO_ERROR) {
143 wcore_errorf(WAFFLE_ERROR_UNKNOWN,
144 "Error in android::SurfaceControl->setLayer");
145 delete pANWContainer;
146 goto error_closeTransaction;
147 }
148
149 pSFContainer->composer_client->closeGlobalTransaction();
150
151 pANWContainer->window = pANWContainer->surface_control->getSurface();
152
153 pSFContainer->composer_client->openGlobalTransaction();
154 iRVal = pANWContainer->surface_control->setSize(width, height);
155 pSFContainer->composer_client->closeGlobalTransaction();
156
157 if (iRVal != NO_ERROR) {
158 wcore_errorf(WAFFLE_ERROR_UNKNOWN,
159 "error in android::SurfaceControl->setSize");
160 delete pANWContainer;
161 goto error;
162 }
163
164 pANWContainer->native_window = pANWContainer->window.get();
165
166 return pANWContainer;
167
168 error_closeTransaction:
169 pSFContainer->composer_client->closeGlobalTransaction();
170
171 error:
172 droid_tear_down_surfaceflinger_link(pSFContainer);
173 return NULL;
174 }
175
176 bool
droid_show_surface(droid_surfaceflinger_container * pSFContainer,droid_ANativeWindow_container * pANWContainer)177 droid_show_surface(
178 droid_surfaceflinger_container* pSFContainer,
179 droid_ANativeWindow_container* pANWContainer)
180 {
181 int iRVal;
182
183 pSFContainer->composer_client->openGlobalTransaction();
184 iRVal = pANWContainer->surface_control->show();
185 pSFContainer->composer_client->closeGlobalTransaction();
186
187 if (iRVal != NO_ERROR) {
188 wcore_errorf(WAFFLE_ERROR_UNKNOWN,
189 "Error in android::SurfaceControl->show");
190 return false;
191 }
192 return true;
193 }
194
195 bool
droid_resize_surface(droid_surfaceflinger_container * pSFContainer,droid_ANativeWindow_container * pANWContainer,int width,int height)196 droid_resize_surface(
197 droid_surfaceflinger_container* pSFContainer,
198 droid_ANativeWindow_container* pANWContainer,
199 int width,
200 int height)
201 {
202 int iRVal;
203
204 pSFContainer->composer_client->openGlobalTransaction();
205 iRVal = pANWContainer->surface_control->setSize(width, height);
206 pSFContainer->composer_client->closeGlobalTransaction();
207
208 if (iRVal != NO_ERROR) {
209 wcore_errorf(WAFFLE_ERROR_UNKNOWN,
210 "Error in android::SurfaceControl->setSize");
211 return false;
212 }
213 return true;
214 }
215
216 void
droid_destroy_surface(droid_surfaceflinger_container * pSFContainer,droid_ANativeWindow_container * pANWContainer)217 droid_destroy_surface(
218 droid_surfaceflinger_container* pSFContainer,
219 droid_ANativeWindow_container* pANWContainer)
220 {
221 pSFContainer->composer_client->openGlobalTransaction();
222 pANWContainer->surface_control->clear();
223 pSFContainer->composer_client->closeGlobalTransaction();
224 delete pANWContainer;
225 }
226
227
228 void
droid_tear_down_surfaceflinger_link(waffle::droid_surfaceflinger_container * pSFContainer)229 droid_tear_down_surfaceflinger_link(
230 waffle::droid_surfaceflinger_container* pSFContainer)
231 {
232 if( pSFContainer == NULL)
233 return;
234
235 if (pSFContainer->composer_client != NULL) {
236 pSFContainer->composer_client->dispose();
237 pSFContainer->composer_client = NULL;
238 }
239
240 delete pSFContainer;
241 }
242
243 }; // namespace waffle
244
245 extern "C" struct droid_surfaceflinger_container*
droid_init_gl()246 droid_init_gl()
247 {
248 return reinterpret_cast<droid_surfaceflinger_container*>(
249 waffle::droid_setup_surfaceflinger_link());
250 }
251 extern "C" bool
droid_deinit_gl(droid_surfaceflinger_container * pSFContainer)252 droid_deinit_gl(droid_surfaceflinger_container* pSFContainer)
253 {
254 waffle::droid_tear_down_surfaceflinger_link(
255 reinterpret_cast<waffle::droid_surfaceflinger_container*>
256 (pSFContainer));
257 return true;
258 }
259
260 extern "C" droid_ANativeWindow_container*
droid_create_surface(int width,int height,droid_surfaceflinger_container * pSFContainer)261 droid_create_surface(
262 int width,
263 int height,
264 droid_surfaceflinger_container* pSFContainer)
265 {
266 waffle::droid_ANativeWindow_container* container =
267 waffle::droid_setup_surface(
268 width, height,
269 reinterpret_cast<waffle::droid_surfaceflinger_container*> (pSFContainer));
270 return reinterpret_cast<droid_ANativeWindow_container*>(container);
271 }
272
273 extern "C" bool
droid_show_surface(droid_surfaceflinger_container * pSFContainer,droid_ANativeWindow_container * pANWContainer)274 droid_show_surface(
275 droid_surfaceflinger_container* pSFContainer,
276 droid_ANativeWindow_container* pANWContainer)
277 {
278 return waffle::droid_show_surface(
279 reinterpret_cast<waffle::droid_surfaceflinger_container*>
280 (pSFContainer),
281 reinterpret_cast<waffle::droid_ANativeWindow_container*>
282 (pANWContainer));
283 }
284
285 extern "C" bool
droid_resize_surface(droid_surfaceflinger_container * pSFContainer,droid_ANativeWindow_container * pANWContainer,int height,int width)286 droid_resize_surface(
287 droid_surfaceflinger_container* pSFContainer,
288 droid_ANativeWindow_container* pANWContainer,
289 int height,
290 int width)
291 {
292 return waffle::droid_resize_surface(
293 reinterpret_cast<waffle::droid_surfaceflinger_container*>
294 (pSFContainer),
295 reinterpret_cast<waffle::droid_ANativeWindow_container*>
296 (pANWContainer), height, width);
297 }
298
299 extern "C" void
droid_destroy_surface(droid_surfaceflinger_container * pSFContainer,droid_ANativeWindow_container * pANWContainer)300 droid_destroy_surface(
301 droid_surfaceflinger_container* pSFContainer,
302 droid_ANativeWindow_container* pANWContainer)
303 {
304 return waffle::droid_destroy_surface(
305 reinterpret_cast<waffle::droid_surfaceflinger_container*>
306 (pSFContainer),
307 reinterpret_cast<waffle::droid_ANativeWindow_container*>
308 (pANWContainer));
309 }
310