Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
/*
* Copyright (c) 2012 Carsten Munk <carsten.munk@gmail.com>
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
#include <android-config.h>
#include <EGL/egl.h>
#include <GLES2/gl2.h>
#include <assert.h>
#include <stdio.h>
#include <math.h>
#include <stddef.h>
#include <hwcomposer_window.h>
#include <hardware/hardware.h>
#include <hardware/hwcomposer.h>
#include <malloc.h>
#include <sync/sync.h>
const char vertex_src [] =
" \
attribute vec4 position; \
varying mediump vec2 pos; \
uniform vec4 offset; \
\
void main() \
{ \
gl_Position = position + offset; \
pos = position.xy; \
} \
";
const char fragment_src [] =
" \
varying mediump vec2 pos; \
uniform mediump float phase; \
\
void main() \
{ \
gl_FragColor = vec4( 1., 0.9, 0.7, 1.0 ) * \
cos( 30.*sqrt(pos.x*pos.x + 1.5*pos.y*pos.y) \
+ atan(pos.y,pos.x) - phase ); \
} \
";
GLuint load_shader(const char *shader_source, GLenum type)
{
GLuint shader = glCreateShader(type);
glShaderSource(shader, 1, &shader_source, NULL);
glCompileShader(shader);
return shader;
}
GLfloat norm_x = 0.0;
GLfloat norm_y = 0.0;
GLfloat offset_x = 0.0;
GLfloat offset_y = 0.0;
GLfloat p1_pos_x = 0.0;
GLfloat p1_pos_y = 0.0;
GLint phase_loc;
GLint offset_loc;
GLint position_loc;
const float vertexArray[] = {
0.0, 1.0, 0.0,
-1., 0.0, 0.0,
0.0, -1.0, 0.0,
1., 0.0, 0.0,
0.0, 1., 0.0
};
class HWComposer : public HWComposerNativeWindow
{
private:
hwc_layer_1_t *fblayer;
hwc_composer_device_1_t *hwcdevice;
hwc_display_contents_1_t **mlist;
protected:
void present(HWComposerNativeWindowBuffer *buffer);
public:
HWComposer(unsigned int width, unsigned int height, unsigned int format, hwc_composer_device_1_t *device, hwc_display_contents_1_t **mList, hwc_layer_1_t *layer);
void set();
};
HWComposer::HWComposer(unsigned int width, unsigned int height, unsigned int format, hwc_composer_device_1_t *device, hwc_display_contents_1_t **mList, hwc_layer_1_t *layer) : HWComposerNativeWindow(width, height, format)
{
fblayer = layer;
hwcdevice = device;
mlist = mList;
}
void HWComposer::present(HWComposerNativeWindowBuffer *buffer)
{
int oldretire = mlist[0]->retireFenceFd;
mlist[0]->retireFenceFd = -1;
fblayer->handle = buffer->handle;
fblayer->acquireFenceFd = getFenceBufferFd(buffer);
fblayer->releaseFenceFd = -1;
int err = hwcdevice->prepare(hwcdevice, 2, mlist);
assert(err == 0);
err = hwcdevice->set(hwcdevice, 2, mlist);
assert(err == 0);
setFenceBufferFd(buffer, fblayer->releaseFenceFd);
if (oldretire != -1)
{
sync_wait(oldretire, -1);
close(oldretire);
}
}
int main(int argc, char **argv)
{
EGLDisplay display;
EGLConfig ecfg;
EGLint num_config;
EGLint attr[] = { // some attributes to set up our egl-interface
EGL_BUFFER_SIZE, 32,
EGL_RENDERABLE_TYPE,
EGL_OPENGL_ES2_BIT,
EGL_NONE
};
EGLSurface surface;
EGLint ctxattr[] = {
EGL_CONTEXT_CLIENT_VERSION, 2,
EGL_NONE
};
EGLContext context;
EGLBoolean rv;
int err;
hw_module_t *hwcModule = 0;
hwc_composer_device_1_t *hwcDevicePtr = 0;
err = hw_get_module(HWC_HARDWARE_MODULE_ID, (const hw_module_t **) &hwcModule);
assert(err == 0);
err = hwc_open_1(hwcModule, &hwcDevicePtr);
assert(err == 0);
hwcDevicePtr->blank(hwcDevicePtr, 0, 0);
uint32_t configs[5];
size_t numConfigs = 5;
err = hwcDevicePtr->getDisplayConfigs(hwcDevicePtr, 0, configs, &numConfigs);
assert (err == 0);
int32_t attr_values[2];
uint32_t attributes[] = { HWC_DISPLAY_WIDTH, HWC_DISPLAY_HEIGHT, HWC_DISPLAY_NO_ATTRIBUTE };
hwcDevicePtr->getDisplayAttributes(hwcDevicePtr, 0,
configs[0], attributes, attr_values);
printf("width: %i height: %i\n", attr_values[0], attr_values[1]);
size_t size = sizeof(hwc_display_contents_1_t) + 2 * sizeof(hwc_layer_1_t);
hwc_display_contents_1_t *list = (hwc_display_contents_1_t *) malloc(size);
hwc_display_contents_1_t **mList = (hwc_display_contents_1_t **) malloc(HWC_NUM_DISPLAY_TYPES * sizeof(hwc_display_contents_1_t *));
const hwc_rect_t r = { 0, 0, attr_values[0], attr_values[1] };
int counter = 0;
for (; counter < HWC_NUM_DISPLAY_TYPES; counter++)
mList[counter] = list;
hwc_layer_1_t *layer = &list->hwLayers[0];
memset(layer, 0, sizeof(hwc_layer_1_t));
layer->compositionType = HWC_FRAMEBUFFER;
layer->hints = 0;
layer->flags = 0;
layer->handle = 0;
layer->transform = 0;
layer->blending = HWC_BLENDING_NONE;
layer->sourceCrop = r;
layer->displayFrame = r;
layer->visibleRegionScreen.numRects = 1;
layer->visibleRegionScreen.rects = &layer->displayFrame;
layer->acquireFenceFd = -1;
layer->releaseFenceFd = -1;
layer = &list->hwLayers[1];
memset(layer, 0, sizeof(hwc_layer_1_t));
layer->compositionType = HWC_FRAMEBUFFER_TARGET;
layer->hints = 0;
layer->flags = 0;
layer->handle = 0;
layer->transform = 0;
layer->blending = HWC_BLENDING_NONE;
layer->sourceCrop = r;
layer->displayFrame = r;
layer->visibleRegionScreen.numRects = 1;
layer->visibleRegionScreen.rects = &layer->displayFrame;
layer->acquireFenceFd = -1;
layer->releaseFenceFd = -1;
list->retireFenceFd = -1;
list->flags = HWC_GEOMETRY_CHANGED;
list->numHwLayers = 2;
HWComposer *win = new HWComposer(attr_values[0], attr_values[1], HAL_PIXEL_FORMAT_RGBA_8888, hwcDevicePtr, mList, &list->hwLayers[1]);
display = eglGetDisplay(NULL);
assert(eglGetError() == EGL_SUCCESS);
assert(display != EGL_NO_DISPLAY);
rv = eglInitialize(display, 0, 0);
assert(eglGetError() == EGL_SUCCESS);
assert(rv == EGL_TRUE);
eglChooseConfig((EGLDisplay) display, attr, &ecfg, 1, &num_config);
assert(eglGetError() == EGL_SUCCESS);
assert(rv == EGL_TRUE);
surface = eglCreateWindowSurface((EGLDisplay) display, ecfg, (EGLNativeWindowType) static_cast<ANativeWindow *> (win), NULL);
assert(eglGetError() == EGL_SUCCESS);
assert(surface != EGL_NO_SURFACE);
context = eglCreateContext((EGLDisplay) display, ecfg, EGL_NO_CONTEXT, ctxattr);
assert(eglGetError() == EGL_SUCCESS);
assert(context != EGL_NO_CONTEXT);
assert(eglMakeCurrent((EGLDisplay) display, surface, surface, context) == EGL_TRUE);
const char *version = (const char *)glGetString(GL_VERSION);
assert(version);
printf("%s\n",version);
GLuint vertexShader = load_shader ( vertex_src , GL_VERTEX_SHADER ); // load vertex shader
GLuint fragmentShader = load_shader ( fragment_src , GL_FRAGMENT_SHADER ); // load fragment shader
GLuint shaderProgram = glCreateProgram (); // create program object
glAttachShader ( shaderProgram, vertexShader ); // and attach both...
glAttachShader ( shaderProgram, fragmentShader ); // ... shaders to it
glLinkProgram ( shaderProgram ); // link the program
glUseProgram ( shaderProgram ); // and select it for usage
//// now get the locations (kind of handle) of the shaders variables
position_loc = glGetAttribLocation ( shaderProgram , "position" );
phase_loc = glGetUniformLocation ( shaderProgram , "phase" );
offset_loc = glGetUniformLocation ( shaderProgram , "offset" );
if ( position_loc < 0 || phase_loc < 0 || offset_loc < 0 ) {
return 1;
}
//glViewport ( 0 , 0 , 800, 600); // commented out so it uses the initial window dimensions
glClearColor ( 1. , 1. , 1. , 1.); // background color
float phase = 0;
int i, oldretire = -1, oldrelease = -1, oldrelease2 = -1;
for (i=0; i<1020*60; ++i) {
glClear(GL_COLOR_BUFFER_BIT);
glUniform1f ( phase_loc , phase ); // write the value of phase to the shaders phase
phase = fmodf ( phase + 0.5f , 2.f * 3.141f ); // and update the local variable
glUniform4f ( offset_loc , offset_x , offset_y , 0.0 , 0.0 );
glVertexAttribPointer ( position_loc, 3, GL_FLOAT, GL_FALSE, 0, vertexArray );
glEnableVertexAttribArray ( position_loc );
glDrawArrays ( GL_TRIANGLE_STRIP, 0, 5 );
eglSwapBuffers ( (EGLDisplay) display, surface ); // get the rendered buffer to the screen
}
printf("stop\n");
#if 0
(*egldestroycontext)((EGLDisplay) display, context);
printf("destroyed context\n");
(*egldestroysurface)((EGLDisplay) display, surface);
printf("destroyed surface\n");
(*eglterminate)((EGLDisplay) display);
printf("terminated\n");
android_dlclose(baz);
#endif
}
// vim:ts=4:sw=4:noexpandtab
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.