2 * Copyright (c) 2012 Carsten Munk <carsten.munk@gmail.com>
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
19 #include <GLES2/gl2.h>
24 #include <hwcomposer_window.h>
25 #include <hardware/hardware.h>
26 #include <hardware/hwcomposer.h>
28 #include <sync/sync.h>
30 const char vertex_src
[] =
32 attribute vec4 position; \
33 varying mediump vec2 pos; \
34 uniform vec4 offset; \
38 gl_Position = position + offset; \
44 const char fragment_src
[] =
46 varying mediump vec2 pos; \
47 uniform mediump float phase; \
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 ); \
57 GLuint
load_shader(const char *shader_source
, GLenum type
)
59 GLuint shader
= glCreateShader(type
);
61 glShaderSource(shader
, 1, &shader_source
, NULL
);
62 glCompileShader(shader
);
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;
79 const float vertexArray
[] = {
88 int main(int argc
, char **argv
)
93 EGLint attr
[] = { // some attributes to set up our egl-interface
101 EGL_CONTEXT_CLIENT_VERSION
, 2,
109 hw_module_t
*hwcModule
= 0;
110 hwc_composer_device_1_t
*hwcDevicePtr
= 0;
112 err
= hw_get_module(HWC_HARDWARE_MODULE_ID
, (const hw_module_t
**) &hwcModule
);
115 err
= hwc_open_1(hwcModule
, &hwcDevicePtr
);
118 hwcDevicePtr
->blank(hwcDevicePtr
, 0, 0);
121 size_t numConfigs
= 5;
123 err
= hwcDevicePtr
->getDisplayConfigs(hwcDevicePtr
, 0, configs
, &numConfigs
);
126 int32_t attr_values
[2];
127 uint32_t attributes
[] = { HWC_DISPLAY_WIDTH
, HWC_DISPLAY_HEIGHT
, HWC_DISPLAY_NO_ATTRIBUTE
};
129 hwcDevicePtr
->getDisplayAttributes(hwcDevicePtr
, 0,
130 configs
[0], attributes
, attr_values
);
132 printf("width: %i height: %i\n", attr_values
[0], attr_values
[1]);
134 HWComposerNativeWindow
*win
= new HWComposerNativeWindow(attr_values
[0], attr_values
[1], HAL_PIXEL_FORMAT_RGBA_8888
);
137 display
= eglGetDisplay(NULL
);
138 assert(eglGetError() == EGL_SUCCESS
);
139 assert(display
!= EGL_NO_DISPLAY
);
141 rv
= eglInitialize(display
, 0, 0);
142 assert(eglGetError() == EGL_SUCCESS
);
143 assert(rv
== EGL_TRUE
);
145 eglChooseConfig((EGLDisplay
) display
, attr
, &ecfg
, 1, &num_config
);
146 assert(eglGetError() == EGL_SUCCESS
);
147 assert(rv
== EGL_TRUE
);
149 surface
= eglCreateWindowSurface((EGLDisplay
) display
, ecfg
, (EGLNativeWindowType
) static_cast<ANativeWindow
*> (win
), NULL
);
150 assert(eglGetError() == EGL_SUCCESS
);
151 assert(surface
!= EGL_NO_SURFACE
);
153 context
= eglCreateContext((EGLDisplay
) display
, ecfg
, EGL_NO_CONTEXT
, ctxattr
);
154 assert(eglGetError() == EGL_SUCCESS
);
155 assert(context
!= EGL_NO_CONTEXT
);
157 assert(eglMakeCurrent((EGLDisplay
) display
, surface
, surface
, context
) == EGL_TRUE
);
159 const char *version
= (const char *)glGetString(GL_VERSION
);
161 printf("%s\n",version
);
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] };
169 for (; counter
< HWC_NUM_DISPLAY_TYPES
; counter
++)
170 mList
[counter
] = list
;
172 hwc_layer_1_t
*layer
= &list
->hwLayers
[0];
173 memset(layer
, 0, sizeof(hwc_layer_1_t
));
174 layer
->compositionType
= HWC_FRAMEBUFFER
;
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
;
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;
201 list
->retireFenceFd
= -1;
202 list
->flags
= HWC_GEOMETRY_CHANGED
;
203 list
->numHwLayers
= 2;
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
208 GLuint shaderProgram
= glCreateProgram (); // create program object
209 glAttachShader ( shaderProgram
, vertexShader
); // and attach both...
210 glAttachShader ( shaderProgram
, fragmentShader
); // ... shaders to it
212 glLinkProgram ( shaderProgram
); // link the program
213 glUseProgram ( shaderProgram
); // and select it for usage
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 ) {
223 //glViewport ( 0 , 0 , 800, 600); // commented out so it uses the initial window dimensions
224 glClearColor ( 1. , 1. , 1. , 1.); // background color
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
232 glUniform4f ( offset_loc
, offset_x
, offset_y
, 0.0 , 0.0 );
234 glVertexAttribPointer ( position_loc
, 3, GL_FLOAT
, GL_FALSE
, 0, vertexArray
);
235 glEnableVertexAttribArray ( position_loc
);
236 glDrawArrays ( GL_TRIANGLE_STRIP
, 0, 5 );
238 eglSwapBuffers ( (EGLDisplay
) display
, surface
); // get the rendered buffer to the screen
240 HWComposerNativeWindowBuffer
*front
;
241 win
->lockFrontBuffer(&front
);
243 mList
[0]->hwLayers
[1].handle
= front
->handle
;
244 mList
[0]->hwLayers
[0].handle
= NULL
;
245 mList
[0]->hwLayers
[0].flags
= HWC_SKIP_LAYER
;
247 oldretire
= mList
[0]->retireFenceFd
;
248 oldrelease
= mList
[0]->hwLayers
[1].releaseFenceFd
;
249 oldrelease2
= mList
[0]->hwLayers
[0].releaseFenceFd
;
251 int err
= hwcDevicePtr
->prepare(hwcDevicePtr
, HWC_NUM_DISPLAY_TYPES
, mList
);
254 err
= hwcDevicePtr
->set(hwcDevicePtr
, HWC_NUM_DISPLAY_TYPES
, mList
);
257 assert(mList
[0]->hwLayers
[0].releaseFenceFd
== -1);
259 win
->unlockFrontBuffer(front
);
261 if (oldrelease
!= -1)
263 sync_wait(oldrelease
, -1);
266 if (oldrelease2
!= -1)
268 sync_wait(oldrelease2
, -1);
273 sync_wait(oldretire
, -1);
281 (*egldestroycontext
)((EGLDisplay
) display
, context
);
282 printf("destroyed context\n");
284 (*egldestroysurface
)((EGLDisplay
) display
, surface
);
285 printf("destroyed surface\n");
286 (*eglterminate
)((EGLDisplay
) display
);
287 printf("terminated\n");
288 android_dlclose(baz
);
292 // vim:ts=4:sw=4:noexpandtab