Commit | Line | Data |
---|---|---|
d42e7319 JB |
1 | /* |
2 | * Copyright (C) 2013 Canonical Ltd | |
3 | * | |
4 | * Licensed under the Apache License, Version 2.0 (the "License"); | |
5 | * you may not use this file except in compliance with the License. | |
6 | * You may obtain a copy of the License at | |
7 | * | |
8 | * http://www.apache.org/licenses/LICENSE-2.0 | |
9 | * | |
10 | * Unless required by applicable law or agreed to in writing, software | |
11 | * distributed under the License is distributed on an "AS IS" BASIS, | |
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
13 | * See the License for the specific language governing permissions and | |
14 | * limitations under the License. | |
15 | * | |
16 | * Authored by: Thomas Voss <thomas.voss@canonical.com> | |
17 | * Ricardo Salveti de Araujo <ricardo.salveti@canonical.com> | |
18 | */ | |
19 | ||
20 | #include <hybris/surface_flinger/surface_flinger_compatibility_layer.h> | |
21 | #include <hybris/internal/surface_flinger_compatibility_layer_internal.h> | |
22 | ||
23 | #include <utils/misc.h> | |
24 | ||
25 | #include <gui/SurfaceComposerClient.h> | |
26 | #include <gui/ISurfaceComposer.h> | |
27 | #include <ui/DisplayInfo.h> | |
28 | #include <ui/PixelFormat.h> | |
29 | #include <ui/Region.h> | |
30 | #include <ui/Rect.h> | |
31 | ||
32 | #include <cassert> | |
33 | #include <cstdio> | |
34 | ||
35 | namespace | |
36 | { | |
37 | void report_failed_to_allocate_surface_flinger_composer_client_on_creation() | |
38 | { | |
39 | printf("Problem allocating an object of type SurfaceComposerClient during client creation"); | |
40 | } | |
41 | ||
42 | void report_failed_to_get_egl_default_display_on_creation() | |
43 | { | |
44 | printf("Problem accessing default egl display during client creation"); | |
45 | } | |
46 | ||
47 | void report_failed_to_initialize_egl_on_creation() | |
48 | { | |
49 | printf("Problem initializing egl during client creation"); | |
50 | } | |
51 | ||
52 | void report_failed_to_choose_egl_config_on_creation() | |
53 | { | |
54 | printf("Problem choosing egl config on creation"); | |
55 | } | |
56 | ||
57 | void report_surface_control_is_null_during_creation() | |
58 | { | |
59 | printf("Could not acquire surface control object during surface creation"); | |
60 | } | |
61 | ||
62 | void report_surface_is_null_during_creation() | |
63 | { | |
64 | printf("Could not acquire surface from surface control during surface creation"); | |
65 | } | |
66 | } | |
67 | ||
68 | void sf_blank(size_t display_id) | |
69 | { | |
70 | android::sp<android::IBinder> display; | |
71 | ||
72 | if (display_id == 0) { | |
73 | display = android::SurfaceComposerClient::getBuiltInDisplay( | |
74 | android::ISurfaceComposer::eDisplayIdMain); | |
75 | } else if (display_id == 1) { | |
76 | display = android::SurfaceComposerClient::getBuiltInDisplay( | |
77 | android::ISurfaceComposer::eDisplayIdHdmi); | |
78 | } else { | |
79 | fprintf(stderr, "Warning: sf_blank invalid display_id (0 || 1)\n"); | |
80 | return; | |
81 | } | |
82 | ||
83 | android::SurfaceComposerClient::blankDisplay(display); | |
84 | } | |
85 | ||
86 | void sf_unblank(size_t display_id) | |
87 | { | |
88 | android::sp<android::IBinder> display; | |
89 | ||
90 | if (display_id == 0) { | |
91 | display = android::SurfaceComposerClient::getBuiltInDisplay( | |
92 | android::ISurfaceComposer::eDisplayIdMain); | |
93 | } else if (display_id == 1) { | |
94 | display = android::SurfaceComposerClient::getBuiltInDisplay( | |
95 | android::ISurfaceComposer::eDisplayIdHdmi); | |
96 | } else { | |
97 | fprintf(stderr, "Warning: sf_unblank invalid display_id (0 || 1)\n"); | |
98 | return; | |
99 | } | |
100 | ||
101 | android::SurfaceComposerClient::unblankDisplay(display); | |
102 | } | |
103 | ||
104 | size_t sf_get_display_width(size_t display_id) | |
105 | { | |
106 | android::sp<android::IBinder> display; | |
107 | ||
108 | if (display_id == 0) { | |
109 | display = android::SurfaceComposerClient::getBuiltInDisplay( | |
110 | android::ISurfaceComposer::eDisplayIdMain); | |
111 | } else if (display_id == 1) { | |
112 | display = android::SurfaceComposerClient::getBuiltInDisplay( | |
113 | android::ISurfaceComposer::eDisplayIdHdmi); | |
114 | } else { | |
115 | fprintf(stderr, "Warning: sf_get_display_width invalid display_id (0 || 1)\n"); | |
116 | return -1; | |
117 | } | |
118 | ||
119 | android::DisplayInfo info; | |
120 | android::SurfaceComposerClient::getDisplayInfo(display, &info); | |
121 | return info.w; | |
122 | } | |
123 | ||
124 | size_t sf_get_display_height(size_t display_id) | |
125 | { | |
126 | android::sp<android::IBinder> display; | |
127 | ||
128 | if (display_id == 0) { | |
129 | display = android::SurfaceComposerClient::getBuiltInDisplay( | |
130 | android::ISurfaceComposer::eDisplayIdMain); | |
131 | } else if (display_id == 1) { | |
132 | display = android::SurfaceComposerClient::getBuiltInDisplay( | |
133 | android::ISurfaceComposer::eDisplayIdHdmi); | |
134 | } else { | |
135 | fprintf(stderr, "Warning: sf_get_display_height invalid display_id (0 || 1)\n"); | |
136 | return -1; | |
137 | } | |
138 | ||
139 | android::DisplayInfo info; | |
140 | android::SurfaceComposerClient::getDisplayInfo(display, &info); | |
141 | return info.h; | |
142 | } | |
143 | ||
144 | SfClient* sf_client_create_full(bool egl_support) | |
145 | { | |
146 | SfClient* client = new SfClient(); | |
147 | ||
148 | client->client = new android::SurfaceComposerClient(); | |
149 | if (client->client == NULL) { | |
150 | report_failed_to_allocate_surface_flinger_composer_client_on_creation(); | |
151 | delete client; | |
152 | return NULL; | |
153 | } | |
154 | ||
155 | client->egl_support = egl_support; | |
156 | if (egl_support) { | |
157 | client->egl_display = eglGetDisplay(EGL_DEFAULT_DISPLAY); | |
158 | if (client->egl_display == EGL_NO_DISPLAY) { | |
159 | report_failed_to_get_egl_default_display_on_creation(); | |
160 | delete client; | |
161 | return NULL; | |
162 | } | |
163 | ||
164 | int major, minor; | |
165 | int rc = eglInitialize(client->egl_display, &major, &minor); | |
166 | if (rc == EGL_FALSE) { | |
167 | report_failed_to_initialize_egl_on_creation(); | |
168 | delete client; | |
169 | return NULL; | |
170 | } | |
171 | ||
172 | EGLint attribs[] = { | |
173 | EGL_SURFACE_TYPE, EGL_WINDOW_BIT, | |
174 | EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT, | |
175 | EGL_NONE | |
176 | }; | |
177 | ||
178 | int n; | |
179 | if (eglChooseConfig(client->egl_display, | |
180 | attribs, | |
181 | &client->egl_config, 1, | |
182 | &n) == EGL_FALSE) { | |
183 | report_failed_to_choose_egl_config_on_creation(); | |
184 | delete client; | |
185 | return NULL; | |
186 | } | |
187 | ||
188 | EGLint context_attribs[] = { | |
189 | EGL_CONTEXT_CLIENT_VERSION, 2, | |
190 | EGL_NONE | |
191 | }; | |
192 | ||
193 | client->egl_context = eglCreateContext( | |
194 | client->egl_display, | |
195 | client->egl_config, | |
196 | EGL_NO_CONTEXT, | |
197 | context_attribs); | |
198 | } | |
199 | ||
200 | return client; | |
201 | } | |
202 | ||
203 | SfClient* sf_client_create() | |
204 | { | |
205 | return sf_client_create_full(true); | |
206 | } | |
207 | ||
208 | EGLDisplay sf_client_get_egl_display(SfClient* client) | |
209 | { | |
210 | assert(client); | |
211 | ||
212 | if (client->egl_support) | |
213 | return client->egl_display; | |
214 | else { | |
215 | fprintf(stderr, "Warning: sf_client_get_egl_display not supported, EGL " | |
216 | "support disabled\n"); | |
217 | return NULL; | |
218 | } | |
219 | } | |
220 | ||
221 | EGLConfig sf_client_get_egl_config(SfClient* client) | |
222 | { | |
223 | assert(client); | |
224 | ||
225 | if (client->egl_support) | |
226 | return client->egl_config; | |
227 | else { | |
228 | fprintf(stderr, "Warning: sf_client_get_egl_config not supported, EGL " | |
229 | "support disabled\n"); | |
230 | return NULL; | |
231 | } | |
232 | } | |
233 | ||
234 | void sf_client_begin_transaction(SfClient* client) | |
235 | { | |
236 | assert(client); | |
237 | client->client->openGlobalTransaction(); | |
238 | } | |
239 | ||
240 | void sf_client_end_transaction(SfClient* client) | |
241 | { | |
242 | assert(client); | |
243 | client->client->closeGlobalTransaction(); | |
244 | } | |
245 | ||
246 | SfSurface* sf_surface_create(SfClient* client, SfSurfaceCreationParameters* params) | |
247 | { | |
248 | assert(client); | |
249 | assert(params); | |
250 | ||
251 | SfSurface* surface = new SfSurface(); | |
252 | surface->client = client; | |
253 | surface->surface_control = surface->client->client->createSurface( | |
254 | android::String8(params->name), | |
255 | params->w, | |
256 | params->h, | |
257 | android::PIXEL_FORMAT_RGBA_8888, | |
258 | 0x300); | |
259 | ||
260 | if (surface->surface_control == NULL) { | |
261 | report_surface_control_is_null_during_creation(); | |
262 | delete(surface); | |
263 | return NULL; | |
264 | } | |
265 | ||
266 | surface->surface = surface->surface_control->getSurface(); | |
267 | ||
268 | if (surface->surface == NULL) { | |
269 | report_surface_is_null_during_creation(); | |
270 | delete(surface); | |
271 | return NULL; | |
272 | } | |
273 | ||
274 | sf_client_begin_transaction(client); | |
275 | { | |
276 | surface->surface_control->setPosition(params->x, params->y); | |
277 | surface->surface_control->setLayer(params->layer); | |
278 | surface->surface_control->setAlpha(params->alpha); | |
279 | } | |
280 | sf_client_end_transaction(client); | |
281 | ||
282 | if (params->create_egl_window_surface) { | |
283 | if (client->egl_support) { | |
284 | android::sp<ANativeWindow> anw(surface->surface); | |
285 | surface->egl_surface = eglCreateWindowSurface( | |
286 | surface->client->egl_display, | |
287 | surface->client->egl_config, | |
288 | anw.get(), | |
289 | NULL); | |
290 | } else | |
291 | fprintf(stderr, "Warning: params->create_egl_window_surface not " | |
292 | "supported, EGL support disabled\n"); | |
293 | } | |
294 | ||
295 | return surface; | |
296 | } | |
297 | ||
298 | EGLSurface sf_surface_get_egl_surface(SfSurface* surface) | |
299 | { | |
300 | assert(surface); | |
301 | ||
302 | if (surface->client->egl_support) | |
303 | return surface->egl_surface; | |
304 | else { | |
305 | fprintf(stderr, "Warning: sf_surface_get_egl_surface not supported, " | |
306 | "EGL support disabled\n"); | |
307 | return NULL; | |
308 | } | |
309 | } | |
310 | ||
311 | EGLNativeWindowType sf_surface_get_egl_native_window(SfSurface* surface) | |
312 | { | |
313 | assert(surface); | |
314 | return surface->surface.get(); | |
315 | } | |
316 | ||
317 | void sf_surface_make_current(SfSurface* surface) | |
318 | { | |
319 | assert(surface); | |
320 | ||
321 | if (surface->client->egl_support) { | |
322 | eglMakeCurrent( | |
323 | surface->client->egl_display, | |
324 | surface->egl_surface, | |
325 | surface->egl_surface, | |
326 | surface->client->egl_context); | |
327 | } else { | |
328 | fprintf(stderr, "Warning: sf_surface_make_current not supported, EGL " | |
329 | "support disabled\n"); | |
330 | } | |
331 | } | |
332 | ||
333 | void sf_surface_move_to(SfSurface* surface, int x, int y) | |
334 | { | |
335 | assert(surface); | |
336 | surface->surface_control->setPosition(x, y); | |
337 | } | |
338 | ||
339 | void sf_surface_set_size(SfSurface* surface, int w, int h) | |
340 | { | |
341 | assert(surface); | |
342 | surface->surface_control->setSize(w, h); | |
343 | } | |
344 | ||
345 | void sf_surface_set_layer(SfSurface* surface, int layer) | |
346 | { | |
347 | assert(surface); | |
348 | surface->surface_control->setLayer(layer); | |
349 | } | |
350 | ||
351 | void sf_surface_set_alpha(SfSurface* surface, float alpha) | |
352 | { | |
353 | assert(surface); | |
354 | surface->surface_control->setAlpha(alpha); | |
355 | } |