Imported Upstream version 0.1.0+git20131207+e452e83
[deb_libhybris.git] / hybris / tests / test_hwcomposer.cpp
1 /*
2 * Copyright (c) 2012 Carsten Munk <carsten.munk@gmail.com>
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 */
17
18 #include <EGL/egl.h>
19 #include <GLES2/gl2.h>
20 #include <assert.h>
21 #include <stdio.h>
22 #include <math.h>
23 #include <stddef.h>
24 #include <hwcomposer_window.h>
25 #include <hardware/hardware.h>
26 #include <hardware/hwcomposer.h>
27 #include <malloc.h>
28 #include <sync/sync.h>
29
30 const char vertex_src [] =
31 " \
32 attribute vec4 position; \
33 varying mediump vec2 pos; \
34 uniform vec4 offset; \
35 \
36 void main() \
37 { \
38 gl_Position = position + offset; \
39 pos = position.xy; \
40 } \
41 ";
42
43
44 const char fragment_src [] =
45 " \
46 varying mediump vec2 pos; \
47 uniform mediump float phase; \
48 \
49 void main() \
50 { \
51 gl_FragColor = vec4( 1., 0.9, 0.7, 1.0 ) * \
52 cos( 30.*sqrt(pos.x*pos.x + 1.5*pos.y*pos.y) \
53 + atan(pos.y,pos.x) - phase ); \
54 } \
55 ";
56
57 GLuint load_shader(const char *shader_source, GLenum type)
58 {
59 GLuint shader = glCreateShader(type);
60
61 glShaderSource(shader, 1, &shader_source, NULL);
62 glCompileShader(shader);
63
64 return shader;
65 }
66
67
68 GLfloat norm_x = 0.0;
69 GLfloat norm_y = 0.0;
70 GLfloat offset_x = 0.0;
71 GLfloat offset_y = 0.0;
72 GLfloat p1_pos_x = 0.0;
73 GLfloat p1_pos_y = 0.0;
74
75 GLint phase_loc;
76 GLint offset_loc;
77 GLint position_loc;
78
79 const float vertexArray[] = {
80 0.0, 1.0, 0.0,
81 -1., 0.0, 0.0,
82 0.0, -1.0, 0.0,
83 1., 0.0, 0.0,
84 0.0, 1., 0.0
85 };
86
87
88 int main(int argc, char **argv)
89 {
90 EGLDisplay display;
91 EGLConfig ecfg;
92 EGLint num_config;
93 EGLint attr[] = { // some attributes to set up our egl-interface
94 EGL_BUFFER_SIZE, 32,
95 EGL_RENDERABLE_TYPE,
96 EGL_OPENGL_ES2_BIT,
97 EGL_NONE
98 };
99 EGLSurface surface;
100 EGLint ctxattr[] = {
101 EGL_CONTEXT_CLIENT_VERSION, 2,
102 EGL_NONE
103 };
104 EGLContext context;
105
106 EGLBoolean rv;
107
108 int err;
109 hw_module_t *hwcModule = 0;
110 hwc_composer_device_1_t *hwcDevicePtr = 0;
111
112 err = hw_get_module(HWC_HARDWARE_MODULE_ID, (const hw_module_t **) &hwcModule);
113 assert(err == 0);
114
115 err = hwc_open_1(hwcModule, &hwcDevicePtr);
116 assert(err == 0);
117
118 hwcDevicePtr->blank(hwcDevicePtr, 0, 0);
119
120 uint32_t configs[5];
121 size_t numConfigs = 5;
122
123 err = hwcDevicePtr->getDisplayConfigs(hwcDevicePtr, 0, configs, &numConfigs);
124 assert (err == 0);
125
126 int32_t attr_values[2];
127 uint32_t attributes[] = { HWC_DISPLAY_WIDTH, HWC_DISPLAY_HEIGHT, HWC_DISPLAY_NO_ATTRIBUTE };
128
129 hwcDevicePtr->getDisplayAttributes(hwcDevicePtr, 0,
130 configs[0], attributes, attr_values);
131
132 printf("width: %i height: %i\n", attr_values[0], attr_values[1]);
133
134 HWComposerNativeWindow *win = new HWComposerNativeWindow(attr_values[0], attr_values[1], HAL_PIXEL_FORMAT_RGBA_8888);
135
136
137 display = eglGetDisplay(NULL);
138 assert(eglGetError() == EGL_SUCCESS);
139 assert(display != EGL_NO_DISPLAY);
140
141 rv = eglInitialize(display, 0, 0);
142 assert(eglGetError() == EGL_SUCCESS);
143 assert(rv == EGL_TRUE);
144
145 eglChooseConfig((EGLDisplay) display, attr, &ecfg, 1, &num_config);
146 assert(eglGetError() == EGL_SUCCESS);
147 assert(rv == EGL_TRUE);
148
149 surface = eglCreateWindowSurface((EGLDisplay) display, ecfg, (EGLNativeWindowType) static_cast<ANativeWindow *> (win), NULL);
150 assert(eglGetError() == EGL_SUCCESS);
151 assert(surface != EGL_NO_SURFACE);
152
153 context = eglCreateContext((EGLDisplay) display, ecfg, EGL_NO_CONTEXT, ctxattr);
154 assert(eglGetError() == EGL_SUCCESS);
155 assert(context != EGL_NO_CONTEXT);
156
157 assert(eglMakeCurrent((EGLDisplay) display, surface, surface, context) == EGL_TRUE);
158
159 const char *version = (const char *)glGetString(GL_VERSION);
160 assert(version);
161 printf("%s\n",version);
162
163 size_t size = sizeof(hwc_display_contents_1_t) + 2 * sizeof(hwc_layer_1_t);
164 hwc_display_contents_1_t *list = (hwc_display_contents_1_t *) malloc(size);
165 hwc_display_contents_1_t **mList = (hwc_display_contents_1_t **) malloc(HWC_NUM_DISPLAY_TYPES * sizeof(hwc_display_contents_1_t *));
166 const hwc_rect_t r = { 0, 0, attr_values[0], attr_values[1] };
167
168 int counter = 0;
169 for (; counter < HWC_NUM_DISPLAY_TYPES; counter++)
170 mList[counter] = list;
171
172 hwc_layer_1_t *layer = &list->hwLayers[0];
173 memset(layer, 0, sizeof(hwc_layer_1_t));
174 layer->compositionType = HWC_FRAMEBUFFER;
175 layer->hints = 0;
176 layer->flags = 0;
177 layer->handle = 0;
178 layer->transform = 0;
179 layer->blending = HWC_BLENDING_NONE;
180 layer->sourceCrop = r;
181 layer->displayFrame = r;
182 layer->visibleRegionScreen.numRects = 1;
183 layer->visibleRegionScreen.rects = &layer->displayFrame;
184 layer->acquireFenceFd = -1;
185 layer->releaseFenceFd = -1;
186 layer = &list->hwLayers[1];
187 memset(layer, 0, sizeof(hwc_layer_1_t));
188 layer->compositionType = HWC_FRAMEBUFFER_TARGET;
189 layer->hints = 0;
190 layer->flags = 0;
191 layer->handle = 0;
192 layer->transform = 0;
193 layer->blending = HWC_BLENDING_NONE;
194 layer->sourceCrop = r;
195 layer->displayFrame = r;
196 layer->visibleRegionScreen.numRects = 1;
197 layer->visibleRegionScreen.rects = &layer->displayFrame;
198 layer->acquireFenceFd = -1;
199 layer->releaseFenceFd = -1;
200
201 list->retireFenceFd = -1;
202 list->flags = HWC_GEOMETRY_CHANGED;
203 list->numHwLayers = 2;
204
205 GLuint vertexShader = load_shader ( vertex_src , GL_VERTEX_SHADER ); // load vertex shader
206 GLuint fragmentShader = load_shader ( fragment_src , GL_FRAGMENT_SHADER ); // load fragment shader
207
208 GLuint shaderProgram = glCreateProgram (); // create program object
209 glAttachShader ( shaderProgram, vertexShader ); // and attach both...
210 glAttachShader ( shaderProgram, fragmentShader ); // ... shaders to it
211
212 glLinkProgram ( shaderProgram ); // link the program
213 glUseProgram ( shaderProgram ); // and select it for usage
214
215 //// now get the locations (kind of handle) of the shaders variables
216 position_loc = glGetAttribLocation ( shaderProgram , "position" );
217 phase_loc = glGetUniformLocation ( shaderProgram , "phase" );
218 offset_loc = glGetUniformLocation ( shaderProgram , "offset" );
219 if ( position_loc < 0 || phase_loc < 0 || offset_loc < 0 ) {
220 return 1;
221 }
222
223 //glViewport ( 0 , 0 , 800, 600); // commented out so it uses the initial window dimensions
224 glClearColor ( 1. , 1. , 1. , 1.); // background color
225 float phase = 0;
226 int i, oldretire = -1, oldrelease = -1, oldrelease2 = -1;
227 for (i=0; i<1020*60; ++i) {
228 glClear(GL_COLOR_BUFFER_BIT);
229 glUniform1f ( phase_loc , phase ); // write the value of phase to the shaders phase
230 phase = fmodf ( phase + 0.5f , 2.f * 3.141f ); // and update the local variable
231
232 glUniform4f ( offset_loc , offset_x , offset_y , 0.0 , 0.0 );
233
234 glVertexAttribPointer ( position_loc, 3, GL_FLOAT, GL_FALSE, 0, vertexArray );
235 glEnableVertexAttribArray ( position_loc );
236 glDrawArrays ( GL_TRIANGLE_STRIP, 0, 5 );
237
238 eglSwapBuffers ( (EGLDisplay) display, surface ); // get the rendered buffer to the screen
239
240 HWComposerNativeWindowBuffer *front;
241 win->lockFrontBuffer(&front);
242
243 mList[0]->hwLayers[1].handle = front->handle;
244 mList[0]->hwLayers[0].handle = NULL;
245 mList[0]->hwLayers[0].flags = HWC_SKIP_LAYER;
246
247 oldretire = mList[0]->retireFenceFd;
248 oldrelease = mList[0]->hwLayers[1].releaseFenceFd;
249 oldrelease2 = mList[0]->hwLayers[0].releaseFenceFd;
250
251 int err = hwcDevicePtr->prepare(hwcDevicePtr, HWC_NUM_DISPLAY_TYPES, mList);
252 assert(err == 0);
253
254 err = hwcDevicePtr->set(hwcDevicePtr, HWC_NUM_DISPLAY_TYPES, mList);
255 assert(err == 0);
256
257 assert(mList[0]->hwLayers[0].releaseFenceFd == -1);
258
259 win->unlockFrontBuffer(front);
260
261 if (oldrelease != -1)
262 {
263 sync_wait(oldrelease, -1);
264 close(oldrelease);
265 }
266 if (oldrelease2 != -1)
267 {
268 sync_wait(oldrelease2, -1);
269 close(oldrelease2);
270 }
271 if (oldretire != -1)
272 {
273 sync_wait(oldretire, -1);
274 close(oldretire);
275 }
276 }
277
278 printf("stop\n");
279
280 #if 0
281 (*egldestroycontext)((EGLDisplay) display, context);
282 printf("destroyed context\n");
283
284 (*egldestroysurface)((EGLDisplay) display, surface);
285 printf("destroyed surface\n");
286 (*eglterminate)((EGLDisplay) display);
287 printf("terminated\n");
288 android_dlclose(baz);
289 #endif
290 }
291
292 // vim:ts=4:sw=4:noexpandtab