Home | History | Annotate | Download | only in cts
      1 /*
      2  * Copyright (C) 2012 The Android Open Source Project
      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 package android.view.cts;
     17 
     18 import android.graphics.SurfaceTexture;
     19 import android.opengl.GLUtils;
     20 
     21 import junit.framework.Assert;
     22 
     23 import java.util.concurrent.Semaphore;
     24 import java.util.concurrent.atomic.AtomicBoolean;
     25 
     26 import javax.microedition.khronos.egl.EGL10;
     27 import javax.microedition.khronos.egl.EGLConfig;
     28 import javax.microedition.khronos.egl.EGLContext;
     29 import javax.microedition.khronos.egl.EGLDisplay;
     30 import javax.microedition.khronos.egl.EGLSurface;
     31 
     32 public class GLProducerThread extends Thread {
     33     private final int mFrames;
     34     private final int mDelayMs;
     35     private final Semaphore mSemaphore;
     36     private final SurfaceTexture mSurfaceTexture;
     37     private final AtomicBoolean mShouldRender;
     38     private final GLRenderer mRenderer;
     39 
     40     private EGL10 mEgl;
     41     private EGLDisplay mEglDisplay = EGL10.EGL_NO_DISPLAY;
     42     private EGLContext mEglContext = EGL10.EGL_NO_CONTEXT;
     43     private EGLSurface mEglSurface = EGL10.EGL_NO_SURFACE;
     44 
     45     private static final int EGL_CONTEXT_CLIENT_VERSION = 0x3098;
     46     private static final int EGL_OPENGL_ES2_BIT = 4;
     47 
     48     public interface GLRenderer {
     49         void drawFrame(int frame);
     50     }
     51 
     52     private GLProducerThread(SurfaceTexture surfaceTexture, GLRenderer renderer,
     53             AtomicBoolean shouldRender,
     54             int frames, int delayMs, Semaphore semaphore) {
     55         mShouldRender = shouldRender;
     56         mFrames = frames;
     57         mDelayMs = delayMs;
     58         mSemaphore = semaphore;
     59         mSurfaceTexture = surfaceTexture;
     60         mRenderer = renderer;
     61     }
     62 
     63     GLProducerThread(SurfaceTexture surfaceTexture, GLRenderer renderer, int frames, int delayMs,
     64             Semaphore semaphore) {
     65         this(surfaceTexture, renderer, null, frames, delayMs, semaphore);
     66     }
     67 
     68     GLProducerThread(SurfaceTexture surfaceTexture, GLRenderer renderer, AtomicBoolean shouldRender,
     69             int delayMs, Semaphore semaphore) {
     70         this(surfaceTexture, renderer, shouldRender, 0, delayMs, semaphore);
     71     }
     72 
     73     private void initGL() {
     74         mEgl = (EGL10) EGLContext.getEGL();
     75 
     76         mEglDisplay = mEgl.eglGetDisplay(EGL10.EGL_DEFAULT_DISPLAY);
     77         if (mEglDisplay == EGL10.EGL_NO_DISPLAY) {
     78             throw new RuntimeException("eglGetDisplay() failed "
     79                     + GLUtils.getEGLErrorString(mEgl.eglGetError()));
     80         }
     81 
     82         int[] version = new int[2];
     83         if (!mEgl.eglInitialize(mEglDisplay, version)) {
     84             throw new RuntimeException("eglInitialize() failed "
     85                     + GLUtils.getEGLErrorString(mEgl.eglGetError()));
     86         }
     87 
     88         int[] configAttribs = {
     89             EGL10.EGL_BUFFER_SIZE, 32,
     90             EGL10.EGL_ALPHA_SIZE, 8,
     91             EGL10.EGL_BLUE_SIZE, 8,
     92             EGL10.EGL_GREEN_SIZE, 8,
     93             EGL10.EGL_RED_SIZE, 8,
     94             EGL10.EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
     95             EGL10.EGL_SURFACE_TYPE, EGL10.EGL_WINDOW_BIT,
     96             EGL10.EGL_NONE
     97         };
     98 
     99         int[] numConfigs = new int[1];
    100         EGLConfig[] configs = new EGLConfig[1];
    101         if (!mEgl.eglChooseConfig(mEglDisplay, configAttribs, configs, 1, numConfigs)
    102                 || numConfigs[0] == 0) {
    103             throw new RuntimeException("eglChooseConfig() failed");
    104         }
    105 
    106         int[] contextAttribs = {
    107             EGL_CONTEXT_CLIENT_VERSION, 2,
    108             EGL10.EGL_NONE };
    109 
    110         mEglContext = mEgl.eglCreateContext(mEglDisplay,
    111                 configs[0], EGL10.EGL_NO_CONTEXT, contextAttribs);
    112 
    113         mEglSurface = mEgl.eglCreateWindowSurface(mEglDisplay,
    114                 configs[0], mSurfaceTexture, null);
    115 
    116         if (mEglSurface == null || mEglSurface == EGL10.EGL_NO_SURFACE) {
    117             int error = mEgl.eglGetError();
    118             if (error == EGL10.EGL_BAD_NATIVE_WINDOW) {
    119                 throw new RuntimeException(
    120                         "eglCreateWindowSurface() returned EGL_BAD_NATIVE_WINDOW.");
    121             }
    122             throw new RuntimeException("eglCreateWindowSurface() failed "
    123                                        + GLUtils.getEGLErrorString(error));
    124         }
    125 
    126         if (!mEgl.eglMakeCurrent(mEglDisplay, mEglSurface, mEglSurface, mEglContext)) {
    127             throw new RuntimeException("eglMakeCurrent() failed "
    128                                        + GLUtils.getEGLErrorString(mEgl.eglGetError()));
    129         }
    130     }
    131 
    132     private void destroyGL() {
    133         mEgl.eglMakeCurrent(mEglDisplay,
    134                 EGL10.EGL_NO_SURFACE, EGL10.EGL_NO_SURFACE, EGL10.EGL_NO_CONTEXT);
    135         mEgl.eglDestroyContext(mEglDisplay, mEglContext);
    136         mEgl.eglDestroySurface(mEglDisplay, mEglSurface);
    137         mEglContext = EGL10.EGL_NO_CONTEXT;
    138         mEglSurface = EGL10.EGL_NO_SURFACE;
    139     }
    140 
    141     @Override
    142     public void run() {
    143         initGL();
    144 
    145         int frame = 0;
    146         while (frame < mFrames || (mShouldRender != null && mShouldRender.get())) {
    147             if (mRenderer != null) {
    148                 mRenderer.drawFrame(frame);
    149             }
    150             mEgl.eglSwapBuffers(mEglDisplay, mEglSurface);
    151             Assert.assertEquals(EGL10.EGL_SUCCESS, mEgl.eglGetError());
    152             try {
    153                 sleep(mDelayMs);
    154             } catch (InterruptedException e) {
    155             }
    156             frame++;
    157         }
    158 
    159         mSemaphore.release();
    160         destroyGL();
    161     }
    162 }
    163