-
-
Save Nokius/7155721b74138675f975 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
* 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