summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--libs/audioflinger/AudioFlinger.cpp20
-rw-r--r--libs/audioflinger/AudioFlinger.h4
-rw-r--r--libs/surfaceflinger/Layer.cpp4
-rw-r--r--libs/surfaceflinger/SurfaceFlinger.cpp21
-rw-r--r--libs/surfaceflinger/SurfaceFlinger.h1
-rw-r--r--libs/utils/ResourceTypes.cpp12
-rw-r--r--opengl/libs/EGL/Loader.cpp19
-rw-r--r--opengl/tests/gl2_basic/gl2_basic.cpp347
8 files changed, 297 insertions, 131 deletions
diff --git a/libs/audioflinger/AudioFlinger.cpp b/libs/audioflinger/AudioFlinger.cpp
index add358b..e534447 100644
--- a/libs/audioflinger/AudioFlinger.cpp
+++ b/libs/audioflinger/AudioFlinger.cpp
@@ -307,6 +307,9 @@ sp<IAudioTrack> AudioFlinger::createTrack(
if (lStatus == NO_ERROR) {
trackHandle = new TrackHandle(track);
} else {
+ // remove local strong reference to Client before deleting the Track so that the Client
+ // destructor is called by the TrackBase destructor with mLock held
+ client.clear();
track.clear();
}
@@ -707,10 +710,10 @@ void AudioFlinger::audioConfigChanged_l(int event, const sp<ThreadBase>& thread,
}
}
-void AudioFlinger::removeClient(pid_t pid)
+// removeClient_l() must be called with AudioFlinger::mLock held
+void AudioFlinger::removeClient_l(pid_t pid)
{
- LOGV("removeClient() pid %d, tid %d, calling tid %d", pid, gettid(), IPCThreadState::self()->getCallingPid());
- Mutex::Autolock _l(mLock);
+ LOGV("removeClient_l() pid %d, tid %d, calling tid %d", pid, gettid(), IPCThreadState::self()->getCallingPid());
mClients.removeItem(pid);
}
@@ -2078,7 +2081,10 @@ AudioFlinger::ThreadBase::TrackBase::~TrackBase()
}
}
mCblkMemory.clear(); // and free the shared memory
- mClient.clear();
+ if (mClient != NULL) {
+ Mutex::Autolock _l(mClient->audioFlinger()->mLock);
+ mClient.clear();
+ }
}
void AudioFlinger::ThreadBase::TrackBase::releaseBuffer(AudioBufferProvider::Buffer* buffer)
@@ -2712,9 +2718,10 @@ AudioFlinger::Client::Client(const sp<AudioFlinger>& audioFlinger, pid_t pid)
// 1 MB of address space is good for 32 tracks, 8 buffers each, 4 KB/buffer
}
+// Client destructor must be called with AudioFlinger::mLock held
AudioFlinger::Client::~Client()
{
- mAudioFlinger->removeClient(mPid);
+ mAudioFlinger->removeClient_l(mPid);
}
const sp<MemoryDealer>& AudioFlinger::Client::heap() const
@@ -2820,6 +2827,9 @@ sp<IAudioRecord> AudioFlinger::openRecord(
format, channelCount, frameCount, flags);
}
if (recordTrack->getCblk() == NULL) {
+ // remove local strong reference to Client before deleting the RecordTrack so that the Client
+ // destructor is called by the TrackBase destructor with mLock held
+ client.clear();
recordTrack.clear();
lStatus = NO_MEMORY;
goto Exit;
diff --git a/libs/audioflinger/AudioFlinger.h b/libs/audioflinger/AudioFlinger.h
index 7a6641f..3699019 100644
--- a/libs/audioflinger/AudioFlinger.h
+++ b/libs/audioflinger/AudioFlinger.h
@@ -189,6 +189,8 @@ private:
virtual ~Client();
const sp<MemoryDealer>& heap() const;
pid_t pid() const { return mPid; }
+ sp<AudioFlinger> audioFlinger() { return mAudioFlinger; }
+
private:
Client(const Client&);
Client& operator = (const Client&);
@@ -641,7 +643,7 @@ private:
friend class PlaybackThread::Track;
- void removeClient(pid_t pid);
+ void removeClient_l(pid_t pid);
// record thread
diff --git a/libs/surfaceflinger/Layer.cpp b/libs/surfaceflinger/Layer.cpp
index 8dfc2cf..5ff9284 100644
--- a/libs/surfaceflinger/Layer.cpp
+++ b/libs/surfaceflinger/Layer.cpp
@@ -88,7 +88,6 @@ void Layer::destroy()
mBuffers[i].clear();
mWidth = mHeight = 0;
}
- mSurface.clear();
}
sp<LayerBaseClient::Surface> Layer::createSurface() const
@@ -99,7 +98,8 @@ sp<LayerBaseClient::Surface> Layer::createSurface() const
status_t Layer::ditch()
{
// the layer is not on screen anymore. free as much resources as possible
- destroy();
+ //destroy();
+ mSurface.clear();
return NO_ERROR;
}
diff --git a/libs/surfaceflinger/SurfaceFlinger.cpp b/libs/surfaceflinger/SurfaceFlinger.cpp
index e87b563..831c446 100644
--- a/libs/surfaceflinger/SurfaceFlinger.cpp
+++ b/libs/surfaceflinger/SurfaceFlinger.cpp
@@ -1084,9 +1084,12 @@ status_t SurfaceFlinger::removeLayer_l(const sp<LayerBase>& layerBase)
status_t SurfaceFlinger::purgatorizeLayer_l(const sp<LayerBase>& layerBase)
{
- // remove the layer from the main list (through a transaction).
+ // First add the layer to the purgatory list, which makes sure it won't
+ // go away, then remove it from the main list (through a transaction).
ssize_t err = removeLayer_l(layerBase);
-
+ if (err >= 0) {
+ mLayerPurgatory.add(layerBase);
+ }
// it's possible that we don't find a layer, because it might
// have been destroyed already -- this is not technically an error
// from the user because there is a race between BClient::destroySurface(),
@@ -1359,8 +1362,18 @@ status_t SurfaceFlinger::destroySurface(const sp<LayerBaseClient>& layer)
* to use the purgatory.
*/
status_t err = flinger->removeLayer_l(l);
- LOGE_IF(err<0 && err != NAME_NOT_FOUND,
- "error removing layer=%p (%s)", l.get(), strerror(-err));
+ if (err == NAME_NOT_FOUND) {
+ // The surface wasn't in the current list, which means it was
+ // removed already, which means it is in the purgatory,
+ // and need to be removed from there.
+ // This needs to happen from the main thread since its dtor
+ // must run from there (b/c of OpenGL ES). Additionally, we
+ // can't really acquire our internal lock from
+ // destroySurface() -- see postMessage() below.
+ ssize_t idx = flinger->mLayerPurgatory.remove(l);
+ LOGE_IF(idx < 0,
+ "layer=%p is not in the purgatory list", l.get());
+ }
return true;
}
};
diff --git a/libs/surfaceflinger/SurfaceFlinger.h b/libs/surfaceflinger/SurfaceFlinger.h
index f207f85..a34889a 100644
--- a/libs/surfaceflinger/SurfaceFlinger.h
+++ b/libs/surfaceflinger/SurfaceFlinger.h
@@ -312,6 +312,7 @@ private:
volatile int32_t mTransactionCount;
Condition mTransactionCV;
bool mResizeTransationPending;
+ SortedVector< sp<LayerBase> > mLayerPurgatory;
// protected by mStateLock (but we could use another lock)
Tokenizer mTokens;
diff --git a/libs/utils/ResourceTypes.cpp b/libs/utils/ResourceTypes.cpp
index f80843d..a5a8cc9 100644
--- a/libs/utils/ResourceTypes.cpp
+++ b/libs/utils/ResourceTypes.cpp
@@ -1740,7 +1740,11 @@ bool ResTable::getResourceName(uint32_t resID, resource_name* outName) const
const int e = Res_GETENTRY(resID);
if (p < 0) {
- LOGW("No package identifier when getting name for resource number 0x%08x", resID);
+ if (Res_GETPACKAGE(resID)+1 == 0) {
+ LOGW("No package identifier when getting name for resource number 0x%08x", resID);
+ } else {
+ LOGW("Resources don't contain pacakge for resource number 0x%08x", resID);
+ }
return false;
}
if (t < 0) {
@@ -1786,7 +1790,11 @@ ssize_t ResTable::getResource(uint32_t resID, Res_value* outValue, bool mayBeBag
const int e = Res_GETENTRY(resID);
if (p < 0) {
- LOGW("No package identifier when getting value for resource number 0x%08x", resID);
+ if (Res_GETPACKAGE(resID)+1 == 0) {
+ LOGW("No package identifier when getting name for resource number 0x%08x", resID);
+ } else {
+ LOGW("Resources don't contain pacakge for resource number 0x%08x", resID);
+ }
return BAD_INDEX;
}
if (t < 0) {
diff --git a/opengl/libs/EGL/Loader.cpp b/opengl/libs/EGL/Loader.cpp
index d51b333..7e7da1b 100644
--- a/opengl/libs/EGL/Loader.cpp
+++ b/opengl/libs/EGL/Loader.cpp
@@ -222,19 +222,28 @@ void Loader::init_api(void* dso,
}
}
-void *Loader::load_driver(const char* driver, gl_hooks_t* hooks, uint32_t mask)
+void *Loader::load_driver(const char* driver_absolute_path,
+ gl_hooks_t* hooks, uint32_t mask)
{
- void* dso = dlopen(driver, RTLD_NOW | RTLD_LOCAL);
- if (dso == 0)
+ if (access(driver_absolute_path, R_OK)) {
+ // this happens often, we don't want to log an error
return 0;
+ }
+
+ void* dso = dlopen(driver_absolute_path, RTLD_NOW | RTLD_LOCAL);
+ if (dso == 0) {
+ const char* err = dlerror();
+ LOGE("load_driver(%s): %s", driver_absolute_path, err?err:"unknown");
+ return 0;
+ }
- LOGD("loaded %s", driver);
+ LOGD("loaded %s", driver_absolute_path);
if (mask & EGL) {
getProcAddress = (getProcAddressType)dlsym(dso, "eglGetProcAddress");
LOGE_IF(!getProcAddress,
- "can't find eglGetProcAddress() in %s", driver);
+ "can't find eglGetProcAddress() in %s", driver_absolute_path);
gl_hooks_t::egl_t* egl = &hooks->egl;
__eglMustCastToProperFunctionPointerType* curr =
diff --git a/opengl/tests/gl2_basic/gl2_basic.cpp b/opengl/tests/gl2_basic/gl2_basic.cpp
index d4887ba..f97d347 100644
--- a/opengl/tests/gl2_basic/gl2_basic.cpp
+++ b/opengl/tests/gl2_basic/gl2_basic.cpp
@@ -21,8 +21,8 @@
#include <sys/resource.h>
#include <EGL/egl.h>
-#include <GLES/gl.h>
-#include <GLES/glext.h>
+#include <GLES2/gl2.h>
+#include <GLES2/gl2ext.h>
#include <utils/Timers.h>
@@ -31,144 +31,267 @@
using namespace android;
-static void printGLString(const char *name, GLenum s)
-{
- fprintf(stderr, "printGLString %s, %d\n", name, s);
-#if 0 // causes hangs
- const char *v = (const char *)glGetString(s);
- int error = glGetError();
- fprintf(stderr, "glGetError() = %d, result of glGetString = %x\n", error,
- (unsigned int)v);
- if ((v < (const char*) 0) || (v > (const char*) 0x10000))
- fprintf(stderr, "GL %s = %s\n", name, v);
- else
- fprintf(stderr, "GL %s = (null) 0x%08x\n", name, (unsigned int) v);
-#endif
+static void printGLString(const char *name, GLenum s) {
+ // fprintf(stderr, "printGLString %s, %d\n", name, s);
+ const char *v = (const char *) glGetString(s);
+ // int error = glGetError();
+ // fprintf(stderr, "glGetError() = %d, result of glGetString = %x\n", error,
+ // (unsigned int) v);
+ // if ((v < (const char*) 0) || (v > (const char*) 0x10000))
+ // fprintf(stderr, "GL %s = %s\n", name, v);
+ // else
+ // fprintf(stderr, "GL %s = (null) 0x%08x\n", name, (unsigned int) v);
+ fprintf(stderr, "GL %s = %s\n", name, v);
}
static const char* eglErrorToString[] = {
- "EGL_SUCCESS", // 0x3000 12288
- "EGL_NOT_INITIALIZED",
- "EGL_BAD_ACCESS", // 0x3002 12290
- "EGL_BAD_ALLOC",
- "EGL_BAD_ATTRIBUTE",
- "EGL_BAD_CONFIG",
- "EGL_BAD_CONTEXT", // 0x3006 12294
- "EGL_BAD_CURRENT_SURFACE",
- "EGL_BAD_DISPLAY",
- "EGL_BAD_MATCH",
- "EGL_BAD_NATIVE_PIXMAP",
- "EGL_BAD_NATIVE_WINDOW",
- "EGL_BAD_PARAMETER", // 0x300c 12300
- "EGL_BAD_SURFACE"
-};
+ "EGL_SUCCESS", // 0x3000 12288
+ "EGL_NOT_INITIALIZED",
+ "EGL_BAD_ACCESS", // 0x3002 12290
+ "EGL_BAD_ALLOC", "EGL_BAD_ATTRIBUTE",
+ "EGL_BAD_CONFIG",
+ "EGL_BAD_CONTEXT", // 0x3006 12294
+ "EGL_BAD_CURRENT_SURFACE", "EGL_BAD_DISPLAY", "EGL_BAD_MATCH",
+ "EGL_BAD_NATIVE_PIXMAP", "EGL_BAD_NATIVE_WINDOW", "EGL_BAD_PARAMETER", // 0x300c 12300
+ "EGL_BAD_SURFACE" };
static void checkEglError(const char* op, EGLBoolean returnVal = EGL_TRUE) {
if (returnVal != EGL_TRUE) {
fprintf(stderr, "%s() returned %d\n", op, returnVal);
}
- for(EGLint error = eglGetError();
- error != EGL_SUCCESS;
- error = eglGetError()) {
+ for (EGLint error = eglGetError(); error != EGL_SUCCESS; error
+ = eglGetError()) {
const char* errorString = "unknown";
if (error >= EGL_SUCCESS && error <= EGL_BAD_SURFACE) {
errorString = eglErrorToString[error - EGL_SUCCESS];
}
- fprintf(stderr, "after %s() eglError %s (0x%x)\n", op,
- errorString, error);
+ fprintf(stderr, "after %s() eglError %s (0x%x)\n", op, errorString,
+ error);
+ }
+}
+
+static void checkGlError(const char* op) {
+ for (GLint error = glGetError(); error; error
+ = glGetError()) {
+ fprintf(stderr, "after %s() glError (0x%x)\n", op, error);
+ }
+}
+
+static const char gVertexShader[] = "attribute vec4 vPosition;\n"
+ "void main() {\n"
+ " gl_Position = vPosition;\n"
+ "}\n";
+
+static const char gFragmentShader[] = "precision mediump float;\n"
+ "void main() {\n"
+ " gl_FragColor = vec4(0.0, 1.0, 0.0, 1.0);\n"
+ "}\n";
+
+GLuint loadShader(GLenum shaderType, const char* pSource) {
+ GLuint shader = glCreateShader(shaderType);
+ if (shader) {
+ glShaderSource(shader, 1, &pSource, NULL);
+ glCompileShader(shader);
+ GLint compiled = 0;
+ glGetShaderiv(shader, GL_COMPILE_STATUS, &compiled);
+ if (!compiled) {
+ GLint infoLen = 0;
+ glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &infoLen);
+ if (infoLen) {
+ char* buf = (char*) malloc(infoLen);
+ if (buf) {
+ glGetShaderInfoLog(shader, infoLen, NULL, buf);
+ fprintf(stderr, "Could not compile shader %d:\n%s\n",
+ shaderType, buf);
+ free(buf);
+ }
+ glDeleteShader(shader);
+ shader = 0;
+ }
+ }
+ }
+ return shader;
+}
+
+GLuint createProgram(const char* pVertexSource, const char* pFragmentSource) {
+ GLuint vertexShader = loadShader(GL_VERTEX_SHADER, pVertexSource);
+ if (!vertexShader) {
+ return 0;
+ }
+
+ GLuint pixelShader = loadShader(GL_FRAGMENT_SHADER, pFragmentSource);
+ if (!pixelShader) {
+ return 0;
+ }
+
+ GLuint program = glCreateProgram();
+ if (program) {
+ glAttachShader(program, vertexShader);
+ checkGlError("glAttachShader");
+ glAttachShader(program, pixelShader);
+ checkGlError("glAttachShader");
+ glLinkProgram(program);
+ GLint linkStatus = GL_FALSE;
+ glGetProgramiv(program, GL_LINK_STATUS, &linkStatus);
+ if (linkStatus != GL_TRUE) {
+ GLint bufLength = 0;
+ glGetProgramiv(program, GL_INFO_LOG_LENGTH, &bufLength);
+ if (bufLength) {
+ char* buf = (char*) malloc(bufLength);
+ if (buf) {
+ glGetProgramInfoLog(program, bufLength, NULL, buf);
+ fprintf(stderr, "Could not link program:\n%s\n", buf);
+ free(buf);
+ }
+ }
+ glDeleteProgram(program);
+ program = 0;
+ }
+ }
+ return program;
+}
+
+GLuint gProgram;
+GLuint gvPositionHandle;
+
+bool setupGraphics(int w, int h) {
+ gProgram = createProgram(gVertexShader, gFragmentShader);
+ if (!gProgram) {
+ return false;
}
+ gvPositionHandle = glGetAttribLocation(gProgram, "vPosition");
+ checkGlError("glGetAttribLocation");
+ fprintf(stderr, "glGetAttribLocation(\"vPosition\") = %d\n",
+ gvPositionHandle);
+
+ glViewport(0, 0, w, h);
+ checkGlError("glViewport");
+ return true;
+}
+
+const GLfloat gTriangleVertices[] = { 0.0f, 0.5f, -0.5f, -0.5f,
+ 0.5f, -0.5f };
+
+void renderFrame() {
+ glClearColor(0.0f, 0.0f, 1.0f, 1.0f);
+ checkGlError("glClearColor");
+ glClear( GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
+ checkGlError("glClear");
+
+ glUseProgram(gProgram);
+ checkGlError("glUseProgram");
+
+ glVertexAttribPointer(gvPositionHandle, 2, GL_FLOAT, GL_FALSE, 0, gTriangleVertices);
+ checkGlError("glVertexAttribPointer");
+ glEnableVertexAttribArray(gvPositionHandle);
+ checkGlError("glEnableVertexAttribArray");
+ glDrawArrays(GL_TRIANGLES, 0, 3);
+ checkGlError("glDrawArrays");
}
-int main(int argc, char** argv)
-{
+int main(int argc, char** argv) {
EGLBoolean returnValue;
EGLConfig configs[2];
EGLint config_count;
- EGLint context_attribs[] = {EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE};
- EGLint s_configAttribs[] = {
- EGL_BUFFER_SIZE, EGL_DONT_CARE,
- EGL_RED_SIZE, 5,
- EGL_GREEN_SIZE, 6,
- EGL_BLUE_SIZE, 5,
- EGL_DEPTH_SIZE, 8,
- EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
- EGL_NONE
- };
-
- EGLint majorVersion;
- EGLint minorVersion;
- EGLContext context;
- EGLSurface surface;
- EGLint w, h;
-
- EGLDisplay dpy;
-
- EGLNativeWindowType window = 0;
- window = android_createDisplaySurface();
-
- checkEglError("<init>");
- dpy = eglGetDisplay(EGL_DEFAULT_DISPLAY);
- checkEglError("eglGetDisplay");
- if (dpy == EGL_NO_DISPLAY) {
- printf("eglGetDisplay returned EGL_NO_DISPLAY.\n");
- return 0;
- }
- returnValue = eglInitialize(dpy, &majorVersion, &minorVersion);
- checkEglError("eglInitialize", returnValue);
- fprintf(stderr, "EGL version %d.%d\n", majorVersion, minorVersion);
-
- returnValue = eglGetConfigs (dpy, configs, 2, &config_count);
- checkEglError("eglGetConfigs", returnValue);
- fprintf(stderr, "Config count: %d\n", config_count);
- for(int i = 0; i < config_count; i++) {
+ EGLint context_attribs[] = { EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE };
+ EGLint s_configAttribs[] = { EGL_BUFFER_SIZE, EGL_DONT_CARE, EGL_RED_SIZE,
+ 5, EGL_GREEN_SIZE, 6, EGL_BLUE_SIZE, 5, EGL_DEPTH_SIZE, 8,
+ EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT, EGL_NONE };
+
+ EGLint s_configAttribs2[] =
+ {
+ EGL_DEPTH_SIZE, 16,
+ EGL_NONE
+ };
+
+ EGLint majorVersion;
+ EGLint minorVersion;
+ EGLContext context;
+ EGLSurface surface;
+ EGLint w, h;
+
+ EGLDisplay dpy;
+
+ EGLNativeWindowType window = 0;
+ window = android_createDisplaySurface();
+
+ checkEglError("<init>");
+ dpy = eglGetDisplay(EGL_DEFAULT_DISPLAY);
+ checkEglError("eglGetDisplay");
+ if (dpy == EGL_NO_DISPLAY) {
+ printf("eglGetDisplay returned EGL_NO_DISPLAY.\n");
+ return 0;
+ }
+
+ returnValue = eglInitialize(dpy, &majorVersion, &minorVersion);
+ checkEglError("eglInitialize", returnValue);
+ fprintf(stderr, "EGL version %d.%d\n", majorVersion, minorVersion);
+ if (returnValue != EGL_TRUE) {
+ printf("eglInitialize failed\n");
+ return 0;
+ }
+
+ returnValue = eglGetConfigs(dpy, configs, 2, &config_count);
+ checkEglError("eglGetConfigs", returnValue);
+ fprintf(stderr, "Config count: %d\n", config_count);
+ for (int i = 0; i < config_count; i++) {
fprintf(stderr, "%d: 0x%08x\n", i, (unsigned int) configs[i]);
- }
+ }
+
#if 0
- EGLConfig config;
- EGLUtils::selectConfigForNativeWindow(dpy, s_configAttribs, window, &config);
- checkEglError("EGLUtils::selectConfigForNativeWindow");
+ EGLConfig config;
+ EGLUtils::selectConfigForNativeWindow(dpy, s_configAttribs, window, &config);
+ checkEglError("EGLUtils::selectConfigForNativeWindow");
#else
- int chooseConfigResult = eglChooseConfig(dpy, s_configAttribs, configs, 2, &config_count);
+ int chooseConfigResult = eglChooseConfig(dpy, s_configAttribs2, configs, 2,
+ &config_count);
checkEglError("eglChooseConfig", chooseConfigResult);
- if (chooseConfigResult != EGL_TRUE )
- {
+ if (chooseConfigResult != EGL_TRUE) {
printf("eglChooseConfig failed\n");
- return 0;
+ return 0;
}
#endif
- surface = eglCreateWindowSurface(dpy, configs[0], window, NULL);
- checkEglError("eglCreateWindowSurface");
- if (surface == EGL_NO_SURFACE)
- {
- printf("gelCreateWindowSurface failed.\n");
- return 0;
- }
- EGLint gl2_0Attribs[] = {EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE};
-
- context = eglCreateContext(dpy, configs[0], EGL_NO_CONTEXT, context_attribs);
- checkEglError("eglCreateContext");
- if (context == EGL_NO_CONTEXT)
- {
+ surface = eglCreateWindowSurface(dpy, configs[0], window, NULL);
+ checkEglError("eglCreateWindowSurface");
+ if (surface == EGL_NO_SURFACE) {
+ printf("gelCreateWindowSurface failed.\n");
+ return 0;
+ }
+ EGLint gl2_0Attribs[] = { EGL_CONTEXT_CLIENT_VERSION, 2, EGL_NONE };
+
+ context = eglCreateContext(dpy, configs[0], EGL_NO_CONTEXT, context_attribs);
+ checkEglError("eglCreateContext");
+ if (context == EGL_NO_CONTEXT) {
printf("eglCreateContext failed\n");
return 0;
- }
- eglMakeCurrent(dpy, surface, surface, context);
- checkEglError("eglMakeCurrent");
- eglQuerySurface(dpy, surface, EGL_WIDTH, &w);
- checkEglError("eglQuerySurface");
- eglQuerySurface(dpy, surface, EGL_HEIGHT, &h);
- checkEglError("eglQuerySurface");
- GLint dim = w<h ? w : h;
-
- fprintf(stderr, "Window dimensions: %d x %d\n", w, h);
-
- printGLString("Version", GL_VERSION);
- printGLString("Vendor", GL_VENDOR);
- printGLString("Renderer", GL_RENDERER);
- printGLString("Extensions", GL_EXTENSIONS);
-
- return 0;
+ }
+ eglMakeCurrent(dpy, surface, surface, context);
+ checkEglError("eglMakeCurrent");
+ eglQuerySurface(dpy, surface, EGL_WIDTH, &w);
+ checkEglError("eglQuerySurface");
+ eglQuerySurface(dpy, surface, EGL_HEIGHT, &h);
+ checkEglError("eglQuerySurface");
+ GLint dim = w < h ? w : h;
+
+ fprintf(stderr, "Window dimensions: %d x %d\n", w, h);
+
+ printGLString("Version", GL_VERSION);
+ printGLString("Vendor", GL_VENDOR);
+ printGLString("Renderer", GL_RENDERER);
+ printGLString("Extensions", GL_EXTENSIONS);
+
+ if(!setupGraphics(w, h)) {
+ fprintf(stderr, "Could not set up graphics.\n");
+ return 0;
+ }
+
+ for (;;) {
+ renderFrame();
+ eglSwapBuffers(dpy, surface);
+ }
+
+ return 0;
}