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