1227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks/* 2227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * Copyright (C) 2011 The Android Open Source Project 3227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * 4227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * Licensed under the Apache License, Version 2.0 (the "License"); 5227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * you may not use this file except in compliance with the License. 6227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * You may obtain a copy of the License at 7227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * 8227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * http://www.apache.org/licenses/LICENSE-2.0 9227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * 10227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * Unless required by applicable law or agreed to in writing, software 11227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * distributed under the License is distributed on an "AS IS" BASIS, 12227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * See the License for the specific language governing permissions and 14227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * limitations under the License. 15227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks */ 16227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks 17227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendrickspackage androidx.media.filterfw; 18227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks 19227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricksimport android.annotation.TargetApi; 20227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricksimport android.graphics.SurfaceTexture; 21227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricksimport android.media.MediaRecorder; 22227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricksimport android.opengl.GLES20; 23227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricksimport android.opengl.GLUtils; 24227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricksimport android.os.Build.VERSION; 25227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricksimport android.util.Log; 26227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricksimport android.view.Surface; 27227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricksimport android.view.SurfaceHolder; 28227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks 29227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricksimport java.nio.ByteBuffer; 30227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricksimport java.util.HashMap; 31227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks 32227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricksimport javax.microedition.khronos.egl.EGL10; 33227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricksimport javax.microedition.khronos.egl.EGLConfig; 34227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricksimport javax.microedition.khronos.egl.EGLContext; 35227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricksimport javax.microedition.khronos.egl.EGLDisplay; 36227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricksimport javax.microedition.khronos.egl.EGLSurface; 37227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks 38227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendrickspublic final class RenderTarget { 39227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks 40227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks private static final int EGL_CONTEXT_CLIENT_VERSION = 0x3098; 41227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks private static final int EGL_OPENGL_ES2_BIT = 4; 42227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks 43227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks // Pre-HC devices do not necessarily support multiple display surfaces. 44227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks private static boolean mSupportsMultipleDisplaySurfaces = (VERSION.SDK_INT >= 11); 45227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks 46227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks /** A Map that tracks which objects are wrapped by EGLSurfaces */ 47227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks private static HashMap<Object, EGLSurface> mSurfaceSources = new HashMap<Object, EGLSurface>(); 48227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks 49227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks /** A Map for performing reference counting over shared objects across RenderTargets */ 50227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks private static HashMap<Object, Integer> mRefCounts = new HashMap<Object, Integer>(); 51227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks 52227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks /** Stores the RenderTarget that is focused on the current thread. */ 53227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks private static ThreadLocal<RenderTarget> mCurrentTarget = new ThreadLocal<RenderTarget>(); 54227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks 55227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks /** The source for the surface used in this target (if any) */ 56227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks private Object mSurfaceSource = null; 57227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks 58227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks /** The cached EGLConfig instance. */ 59227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks private static EGLConfig mEglConfig = null; 60227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks 61227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks /** The display for which the EGLConfig was chosen. We expect only one. */ 62227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks private static EGLDisplay mConfiguredDisplay; 63227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks 64227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks private EGL10 mEgl; 65227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks private EGLDisplay mDisplay; 66227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks private EGLContext mContext; 67227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks private EGLSurface mSurface; 68227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks private int mFbo; 69227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks 70227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks private boolean mOwnsContext; 71227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks private boolean mOwnsSurface; 72227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks 73227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks private static HashMap<EGLContext, ImageShader> mIdShaders 74227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks = new HashMap<EGLContext, ImageShader>(); 75227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks 76227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks private static HashMap<EGLContext, EGLSurface> mDisplaySurfaces 77227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks = new HashMap<EGLContext, EGLSurface>(); 78227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks 79227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks private static int sRedSize = 8; 80227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks private static int sGreenSize = 8; 81227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks private static int sBlueSize = 8; 82227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks private static int sAlphaSize = 8; 83227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks private static int sDepthSize = 0; 84227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks private static int sStencilSize = 0; 85227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks 86227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks public static RenderTarget newTarget(int width, int height) { 87227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks EGL10 egl = (EGL10) EGLContext.getEGL(); 88227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks EGLDisplay eglDisplay = createDefaultDisplay(egl); 89227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks EGLConfig eglConfig = chooseEglConfig(egl, eglDisplay); 90227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks EGLContext eglContext = createContext(egl, eglDisplay, eglConfig); 91227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks EGLSurface eglSurface = createSurface(egl, eglDisplay, width, height); 92227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks RenderTarget result = new RenderTarget(eglDisplay, eglContext, eglSurface, 0, true, true); 93227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks result.addReferenceTo(eglSurface); 94227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks return result; 95227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 96227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks 97227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks public static RenderTarget currentTarget() { 98227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks // As RenderTargets are immutable, we can safely return the last focused instance on this 99227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks // thread, as we know it cannot have changed, and therefore must be current. 100227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks return mCurrentTarget.get(); 101227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 102227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks 103227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks public RenderTarget forTexture(TextureSource texture, int width, int height) { 104227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks // NOTE: We do not need to lookup any previous bindings of this texture to an FBO, as 105227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks // multiple FBOs to a single texture is valid. 106227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks int fbo = GLToolbox.generateFbo(); 107227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks GLES20.glBindFramebuffer(GLES20.GL_FRAMEBUFFER, fbo); 108227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks GLToolbox.checkGlError("glBindFramebuffer"); 109227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks GLES20.glFramebufferTexture2D(GLES20.GL_FRAMEBUFFER, 110227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks GLES20.GL_COLOR_ATTACHMENT0, 111227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks texture.getTarget(), 112227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks texture.getTextureId(), 113227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks 0); 114227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks GLToolbox.checkGlError("glFramebufferTexture2D"); 115227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks return new RenderTarget(mDisplay, mContext, surface(), fbo, false, false); 116227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 117227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks 118227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks public RenderTarget forSurfaceHolder(SurfaceHolder surfaceHolder) { 119227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks EGLConfig eglConfig = chooseEglConfig(mEgl, mDisplay); 120227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks EGLSurface eglSurf = null; 121227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks synchronized (mSurfaceSources) { 122227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks eglSurf = mSurfaceSources.get(surfaceHolder); 123227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks if (eglSurf == null) { 124227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks eglSurf = mEgl.eglCreateWindowSurface(mDisplay, eglConfig, surfaceHolder, null); 125227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks mSurfaceSources.put(surfaceHolder, eglSurf); 126227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 127227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 128227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks checkEglError(mEgl, "eglCreateWindowSurface"); 129227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks checkSurface(mEgl, eglSurf); 130227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks RenderTarget result = new RenderTarget(mDisplay, mContext, eglSurf, 0, false, true); 131227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks result.addReferenceTo(eglSurf); 132227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks result.setSurfaceSource(surfaceHolder); 133227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks return result; 134227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 135227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks 136227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks @TargetApi(11) 137227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks public RenderTarget forSurfaceTexture(SurfaceTexture surfaceTexture) { 138227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks EGLConfig eglConfig = chooseEglConfig(mEgl, mDisplay); 139227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks EGLSurface eglSurf = null; 140227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks synchronized (mSurfaceSources) { 141227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks eglSurf = mSurfaceSources.get(surfaceTexture); 142227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks if (eglSurf == null) { 143227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks eglSurf = mEgl.eglCreateWindowSurface(mDisplay, eglConfig, surfaceTexture, null); 144227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks mSurfaceSources.put(surfaceTexture, eglSurf); 145227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 146227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 147227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks checkEglError(mEgl, "eglCreateWindowSurface"); 148227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks checkSurface(mEgl, eglSurf); 149227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks RenderTarget result = new RenderTarget(mDisplay, mContext, eglSurf, 0, false, true); 150227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks result.setSurfaceSource(surfaceTexture); 151227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks result.addReferenceTo(eglSurf); 152227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks return result; 153227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 154227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks 155227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks @TargetApi(11) 156227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks public RenderTarget forSurface(Surface surface) { 157227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks EGLConfig eglConfig = chooseEglConfig(mEgl, mDisplay); 158227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks EGLSurface eglSurf = null; 159227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks synchronized (mSurfaceSources) { 160227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks eglSurf = mSurfaceSources.get(surface); 161227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks if (eglSurf == null) { 162227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks eglSurf = mEgl.eglCreateWindowSurface(mDisplay, eglConfig, surface, null); 163227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks mSurfaceSources.put(surface, eglSurf); 164227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 165227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 166227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks checkEglError(mEgl, "eglCreateWindowSurface"); 167227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks checkSurface(mEgl, eglSurf); 168227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks RenderTarget result = new RenderTarget(mDisplay, mContext, eglSurf, 0, false, true); 169227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks result.setSurfaceSource(surface); 170227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks result.addReferenceTo(eglSurf); 171227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks return result; 172227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 173227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks 174227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks public static RenderTarget forMediaRecorder(MediaRecorder mediaRecorder) { 175227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks throw new RuntimeException("Not yet implemented MediaRecorder -> RenderTarget!"); 176227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 177227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks 178227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks public static void setEGLConfigChooser(int redSize, int greenSize, int blueSize, int alphaSize, 179227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks int depthSize, int stencilSize) { 180227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks sRedSize = redSize; 181227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks sGreenSize = greenSize; 182227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks sBlueSize = blueSize; 183227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks sAlphaSize = alphaSize; 184227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks sDepthSize = depthSize; 185227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks sStencilSize = stencilSize; 186227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 187227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks 188227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks public void registerAsDisplaySurface() { 189227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks if (!mSupportsMultipleDisplaySurfaces) { 190227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks // Note that while this does in effect change RenderTarget instances (by modifying 191227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks // their returned EGLSurface), breaking the immutability requirement, it does not modify 192227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks // the current target. This is important so that the instance returned in 193227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks // currentTarget() remains accurate. 194227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks EGLSurface currentSurface = mDisplaySurfaces.get(mContext); 195227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks if (currentSurface != null && !currentSurface.equals(mSurface)) { 196227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks throw new RuntimeException("This device supports only a single display surface!"); 197227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } else { 198227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks mDisplaySurfaces.put(mContext, mSurface); 199227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 200227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 201227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 202227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks 203227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks public void unregisterAsDisplaySurface() { 204227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks if (!mSupportsMultipleDisplaySurfaces) { 205227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks mDisplaySurfaces.put(mContext, null); 206227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 207227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 208227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks 209227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks public void focus() { 210227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks RenderTarget current = mCurrentTarget.get(); 211227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks // We assume RenderTargets are immutable, so that we do not need to focus if the current 212227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks // RenderTarget has not changed. 213227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks if (current != this) { 214227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks mEgl.eglMakeCurrent(mDisplay, surface(), surface(), mContext); 215227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks mCurrentTarget.set(this); 216227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 217227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks if (getCurrentFbo() != mFbo) { 218227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks GLES20.glBindFramebuffer(GLES20.GL_FRAMEBUFFER, mFbo); 219227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks GLToolbox.checkGlError("glBindFramebuffer"); 220227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 221227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 222227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks 223227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks public static void focusNone() { 224227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks EGL10 egl = (EGL10) EGLContext.getEGL(); 225227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks egl.eglMakeCurrent(egl.eglGetCurrentDisplay(), 226227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks EGL10.EGL_NO_SURFACE, 227227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks EGL10.EGL_NO_SURFACE, 228227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks EGL10.EGL_NO_CONTEXT); 229227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks mCurrentTarget.set(null); 230227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks checkEglError(egl, "eglMakeCurrent"); 231227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 232227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks 233227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks public void swapBuffers() { 234227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks mEgl.eglSwapBuffers(mDisplay, surface()); 235227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 236227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks 237227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks public EGLContext getContext() { 238227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks return mContext; 239227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 240227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks 241227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks public static EGLContext currentContext() { 242227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks RenderTarget current = RenderTarget.currentTarget(); 243227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks return current != null ? current.getContext() : EGL10.EGL_NO_CONTEXT; 244227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 245227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks 246227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks public void release() { 247227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks if (mOwnsContext) { 248227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks mEgl.eglDestroyContext(mDisplay, mContext); 249227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks mContext = EGL10.EGL_NO_CONTEXT; 250227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 251227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks if (mOwnsSurface) { 252227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks synchronized (mSurfaceSources) { 253227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks if (removeReferenceTo(mSurface)) { 254227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks mEgl.eglDestroySurface(mDisplay, mSurface); 255227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks mSurface = EGL10.EGL_NO_SURFACE; 256227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks mSurfaceSources.remove(mSurfaceSource); 257227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 258227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 259227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 260227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks if (mFbo != 0) { 261227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks GLToolbox.deleteFbo(mFbo); 262227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 263227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 264227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks 265227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks public void readPixelData(ByteBuffer pixels, int width, int height) { 266227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks GLToolbox.readTarget(this, pixels, width, height); 267227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 268227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks 269227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks public ByteBuffer getPixelData(int width, int height) { 270227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks ByteBuffer pixels = ByteBuffer.allocateDirect(width * height * 4); 271227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks GLToolbox.readTarget(this, pixels, width, height); 272227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks return pixels; 273227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 274227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks 275227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks /** 276227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * Returns an identity shader for this context. 277227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * You must not modify this shader. Use {@link ImageShader#createIdentity()} if you need to 278227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks * modify an identity shader. 279227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks */ 280227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks public ImageShader getIdentityShader() { 281227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks ImageShader idShader = mIdShaders.get(mContext); 282227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks if (idShader == null) { 283227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks idShader = ImageShader.createIdentity(); 284227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks mIdShaders.put(mContext, idShader); 285227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 286227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks return idShader; 287227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 288227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks 289227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks @Override 290227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks public String toString() { 291227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks return "RenderTarget(" + mDisplay + ", " + mContext + ", " + mSurface + ", " + mFbo + ")"; 292227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 293227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks 294227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks private void setSurfaceSource(Object source) { 295227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks mSurfaceSource = source; 296227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 297227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks 298227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks private void addReferenceTo(Object object) { 299227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks Integer refCount = mRefCounts.get(object); 300227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks if (refCount != null) { 301227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks mRefCounts.put(object, refCount + 1); 302227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } else { 303227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks mRefCounts.put(object, 1); 304227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 305227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 306227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks 307227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks private boolean removeReferenceTo(Object object) { 308227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks Integer refCount = mRefCounts.get(object); 309227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks if (refCount != null && refCount > 0) { 310227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks --refCount; 311227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks mRefCounts.put(object, refCount); 312227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks return refCount == 0; 313227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } else { 314227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks Log.e("RenderTarget", "Removing reference of already released: " + object + "!"); 315227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks return false; 316227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 317227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 318227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks 319227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks private static EGLConfig chooseEglConfig(EGL10 egl, EGLDisplay display) { 320227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks if (mEglConfig == null || !display.equals(mConfiguredDisplay)) { 321227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks int[] configsCount = new int[1]; 322227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks EGLConfig[] configs = new EGLConfig[1]; 323227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks int[] configSpec = getDesiredConfig(); 324227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks if (!egl.eglChooseConfig(display, configSpec, configs, 1, configsCount)) { 325227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks throw new IllegalArgumentException("EGL Error: eglChooseConfig failed " + 326227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks getEGLErrorString(egl, egl.eglGetError())); 327227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } else if (configsCount[0] > 0) { 328227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks mEglConfig = configs[0]; 329227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks mConfiguredDisplay = display; 330227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 331227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 332227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks return mEglConfig; 333227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 334227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks 335227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks private static int[] getDesiredConfig() { 336227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks return new int[] { 337227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks EGL10.EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT, 338227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks EGL10.EGL_RED_SIZE, sRedSize, 339227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks EGL10.EGL_GREEN_SIZE, sGreenSize, 340227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks EGL10.EGL_BLUE_SIZE, sBlueSize, 341227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks EGL10.EGL_ALPHA_SIZE, sAlphaSize, 342227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks EGL10.EGL_DEPTH_SIZE, sDepthSize, 343227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks EGL10.EGL_STENCIL_SIZE, sStencilSize, 344227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks EGL10.EGL_NONE 345227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks }; 346227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 347227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks 348227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks private RenderTarget(EGLDisplay display, EGLContext context, EGLSurface surface, int fbo, 349227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks boolean ownsContext, boolean ownsSurface) { 350227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks mEgl = (EGL10) EGLContext.getEGL(); 351227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks mDisplay = display; 352227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks mContext = context; 353227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks mSurface = surface; 354227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks mFbo = fbo; 355227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks mOwnsContext = ownsContext; 356227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks mOwnsSurface = ownsSurface; 357227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 358227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks 359227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks private EGLSurface surface() { 360227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks if (mSupportsMultipleDisplaySurfaces) { 361227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks return mSurface; 362227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } else { 363227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks EGLSurface displaySurface = mDisplaySurfaces.get(mContext); 364227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks return displaySurface != null ? displaySurface : mSurface; 365227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 366227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 367227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks 368227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks private static void initEgl(EGL10 egl, EGLDisplay display) { 369227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks int[] version = new int[2]; 370227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks if (!egl.eglInitialize(display, version)) { 371227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks throw new RuntimeException("EGL Error: eglInitialize failed " + 372227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks getEGLErrorString(egl, egl.eglGetError())); 373227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 374227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 375227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks 376227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks private static EGLDisplay createDefaultDisplay(EGL10 egl) { 377227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks EGLDisplay display = egl.eglGetDisplay(EGL10.EGL_DEFAULT_DISPLAY); 378227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks checkDisplay(egl, display); 379227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks initEgl(egl, display); 380227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks return display; 381227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 382227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks 383227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks private static EGLContext createContext(EGL10 egl, EGLDisplay display, EGLConfig config) { 384227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks int[] attrib_list = { EGL_CONTEXT_CLIENT_VERSION, 2, EGL10.EGL_NONE }; 385227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks EGLContext ctxt = egl.eglCreateContext(display, config, EGL10.EGL_NO_CONTEXT, attrib_list); 386227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks checkContext(egl, ctxt); 387227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks return ctxt; 388227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 389227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks 390227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks private static EGLSurface createSurface(EGL10 egl, EGLDisplay display, int width, int height) { 391227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks EGLConfig eglConfig = chooseEglConfig(egl, display); 392227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks int[] attribs = { EGL10.EGL_WIDTH, width, EGL10.EGL_HEIGHT, height, EGL10.EGL_NONE }; 393227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks return egl.eglCreatePbufferSurface(display, eglConfig, attribs); 394227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 395227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks 396227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks private static int getCurrentFbo() { 397227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks int[] result = new int[1]; 398227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks GLES20.glGetIntegerv(GLES20.GL_FRAMEBUFFER_BINDING, result, 0); 399227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks return result[0]; 400227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 401227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks 402227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks private static void checkDisplay(EGL10 egl, EGLDisplay display) { 403227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks if (display == EGL10.EGL_NO_DISPLAY) { 404227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks throw new RuntimeException("EGL Error: Bad display: " 405227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks + getEGLErrorString(egl, egl.eglGetError())); 406227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 407227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 408227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks 409227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks private static void checkContext(EGL10 egl, EGLContext context) { 410227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks if (context == EGL10.EGL_NO_CONTEXT) { 411227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks throw new RuntimeException("EGL Error: Bad context: " 412227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks + getEGLErrorString(egl, egl.eglGetError())); 413227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 414227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 415227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks 416227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks private static void checkSurface(EGL10 egl, EGLSurface surface) { 417227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks if (surface == EGL10.EGL_NO_SURFACE) { 418227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks throw new RuntimeException("EGL Error: Bad surface: " 419227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks + getEGLErrorString(egl, egl.eglGetError())); 420227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 421227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 422227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks 423227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks private static void checkEglError(EGL10 egl, String command) { 424227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks int error = egl.eglGetError(); 425227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks if (error != EGL10.EGL_SUCCESS) { 426227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks throw new RuntimeException("Error executing " + command + "! EGL error = 0x" 427227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks + Integer.toHexString(error)); 428227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 429227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 430227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks 431227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks private static String getEGLErrorString(EGL10 egl, int eglError) { 432227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks if (VERSION.SDK_INT >= 14) { 433227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks return getEGLErrorStringICS(egl, eglError); 434227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } else { 435227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks return "EGL Error 0x" + Integer.toHexString(eglError); 436227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 437227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 438227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks 439227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks @TargetApi(14) 440227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks private static String getEGLErrorStringICS(EGL10 egl, int eglError) { 441227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks return GLUtils.getEGLErrorString(egl.eglGetError()); 442227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks } 443227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks} 444227b47625d7482b5b47ad0e4c70ce0a246236adeBenjamin Hendricks 445