17cabcaccabb00c7f7068a8ebbd55eb43795eefb4Chong Zhang/* 27cabcaccabb00c7f7068a8ebbd55eb43795eefb4Chong Zhang * Copyright (C) 2018 The Android Open Source Project 37cabcaccabb00c7f7068a8ebbd55eb43795eefb4Chong Zhang * 47cabcaccabb00c7f7068a8ebbd55eb43795eefb4Chong Zhang * Licensed under the Apache License, Version 2.0 (the "License"); 57cabcaccabb00c7f7068a8ebbd55eb43795eefb4Chong Zhang * you may not use this file except in compliance with the License. 67cabcaccabb00c7f7068a8ebbd55eb43795eefb4Chong Zhang * You may obtain a copy of the License at 77cabcaccabb00c7f7068a8ebbd55eb43795eefb4Chong Zhang * 87cabcaccabb00c7f7068a8ebbd55eb43795eefb4Chong Zhang * http://www.apache.org/licenses/LICENSE-2.0 97cabcaccabb00c7f7068a8ebbd55eb43795eefb4Chong Zhang * 107cabcaccabb00c7f7068a8ebbd55eb43795eefb4Chong Zhang * Unless required by applicable law or agreed to in writing, software 117cabcaccabb00c7f7068a8ebbd55eb43795eefb4Chong Zhang * distributed under the License is distributed on an "AS IS" BASIS, 127cabcaccabb00c7f7068a8ebbd55eb43795eefb4Chong Zhang * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 137cabcaccabb00c7f7068a8ebbd55eb43795eefb4Chong Zhang * See the License for the specific language governing permissions and 147cabcaccabb00c7f7068a8ebbd55eb43795eefb4Chong Zhang * limitations under the License. 157cabcaccabb00c7f7068a8ebbd55eb43795eefb4Chong Zhang */ 167cabcaccabb00c7f7068a8ebbd55eb43795eefb4Chong Zhang 17db1945bea4e3816a04afe0ad41681cec1d0c074dAlan Viverettepackage androidx.heifwriter; 187cabcaccabb00c7f7068a8ebbd55eb43795eefb4Chong Zhang 197cabcaccabb00c7f7068a8ebbd55eb43795eefb4Chong Zhangimport android.opengl.EGL14; 207cabcaccabb00c7f7068a8ebbd55eb43795eefb4Chong Zhangimport android.opengl.EGLConfig; 217cabcaccabb00c7f7068a8ebbd55eb43795eefb4Chong Zhangimport android.opengl.EGLContext; 227cabcaccabb00c7f7068a8ebbd55eb43795eefb4Chong Zhangimport android.opengl.EGLDisplay; 237cabcaccabb00c7f7068a8ebbd55eb43795eefb4Chong Zhangimport android.opengl.EGLExt; 247cabcaccabb00c7f7068a8ebbd55eb43795eefb4Chong Zhangimport android.opengl.EGLSurface; 257cabcaccabb00c7f7068a8ebbd55eb43795eefb4Chong Zhangimport android.util.Log; 267cabcaccabb00c7f7068a8ebbd55eb43795eefb4Chong Zhangimport android.view.Surface; 277cabcaccabb00c7f7068a8ebbd55eb43795eefb4Chong Zhang 28b1433f75d87710262b14824c98854a4865f98836Aurimas Liutikasimport java.util.Objects; 29b1433f75d87710262b14824c98854a4865f98836Aurimas Liutikas 307cabcaccabb00c7f7068a8ebbd55eb43795eefb4Chong Zhang/** 317cabcaccabb00c7f7068a8ebbd55eb43795eefb4Chong Zhang * Holds state associated with a Surface used for MediaCodec encoder input. 327cabcaccabb00c7f7068a8ebbd55eb43795eefb4Chong Zhang * <p> 337cabcaccabb00c7f7068a8ebbd55eb43795eefb4Chong Zhang * The constructor takes a Surface obtained from MediaCodec.createInputSurface(), and uses that 347cabcaccabb00c7f7068a8ebbd55eb43795eefb4Chong Zhang * to create an EGL window surface. Calls to eglSwapBuffers() cause a frame of data to be sent 357cabcaccabb00c7f7068a8ebbd55eb43795eefb4Chong Zhang * to the video encoder. 367cabcaccabb00c7f7068a8ebbd55eb43795eefb4Chong Zhang * 377cabcaccabb00c7f7068a8ebbd55eb43795eefb4Chong Zhang * @hide 387cabcaccabb00c7f7068a8ebbd55eb43795eefb4Chong Zhang */ 397cabcaccabb00c7f7068a8ebbd55eb43795eefb4Chong Zhangpublic class EglWindowSurface { 407cabcaccabb00c7f7068a8ebbd55eb43795eefb4Chong Zhang private static final String TAG = "EglWindowSurface"; 417cabcaccabb00c7f7068a8ebbd55eb43795eefb4Chong Zhang 427cabcaccabb00c7f7068a8ebbd55eb43795eefb4Chong Zhang private EGLDisplay mEGLDisplay = EGL14.EGL_NO_DISPLAY; 437cabcaccabb00c7f7068a8ebbd55eb43795eefb4Chong Zhang private EGLContext mEGLContext = EGL14.EGL_NO_CONTEXT; 447cabcaccabb00c7f7068a8ebbd55eb43795eefb4Chong Zhang private EGLSurface mEGLSurface = EGL14.EGL_NO_SURFACE; 457cabcaccabb00c7f7068a8ebbd55eb43795eefb4Chong Zhang private EGLConfig[] mConfigs = new EGLConfig[1]; 467cabcaccabb00c7f7068a8ebbd55eb43795eefb4Chong Zhang 477cabcaccabb00c7f7068a8ebbd55eb43795eefb4Chong Zhang private Surface mSurface; 487cabcaccabb00c7f7068a8ebbd55eb43795eefb4Chong Zhang private int mWidth; 497cabcaccabb00c7f7068a8ebbd55eb43795eefb4Chong Zhang private int mHeight; 507cabcaccabb00c7f7068a8ebbd55eb43795eefb4Chong Zhang 517cabcaccabb00c7f7068a8ebbd55eb43795eefb4Chong Zhang /** 527cabcaccabb00c7f7068a8ebbd55eb43795eefb4Chong Zhang * Creates an EglWindowSurface from a Surface. 537cabcaccabb00c7f7068a8ebbd55eb43795eefb4Chong Zhang */ 547cabcaccabb00c7f7068a8ebbd55eb43795eefb4Chong Zhang public EglWindowSurface(Surface surface) { 557cabcaccabb00c7f7068a8ebbd55eb43795eefb4Chong Zhang if (surface == null) { 567cabcaccabb00c7f7068a8ebbd55eb43795eefb4Chong Zhang throw new NullPointerException(); 577cabcaccabb00c7f7068a8ebbd55eb43795eefb4Chong Zhang } 587cabcaccabb00c7f7068a8ebbd55eb43795eefb4Chong Zhang mSurface = surface; 597cabcaccabb00c7f7068a8ebbd55eb43795eefb4Chong Zhang 607cabcaccabb00c7f7068a8ebbd55eb43795eefb4Chong Zhang eglSetup(); 617cabcaccabb00c7f7068a8ebbd55eb43795eefb4Chong Zhang } 627cabcaccabb00c7f7068a8ebbd55eb43795eefb4Chong Zhang 637cabcaccabb00c7f7068a8ebbd55eb43795eefb4Chong Zhang /** 647cabcaccabb00c7f7068a8ebbd55eb43795eefb4Chong Zhang * Prepares EGL. We want a GLES 2.0 context and a surface that supports recording. 657cabcaccabb00c7f7068a8ebbd55eb43795eefb4Chong Zhang */ 667cabcaccabb00c7f7068a8ebbd55eb43795eefb4Chong Zhang private void eglSetup() { 677cabcaccabb00c7f7068a8ebbd55eb43795eefb4Chong Zhang mEGLDisplay = EGL14.eglGetDisplay(EGL14.EGL_DEFAULT_DISPLAY); 68b1433f75d87710262b14824c98854a4865f98836Aurimas Liutikas if (Objects.equals(mEGLDisplay, EGL14.EGL_NO_DISPLAY)) { 697cabcaccabb00c7f7068a8ebbd55eb43795eefb4Chong Zhang throw new RuntimeException("unable to get EGL14 display"); 707cabcaccabb00c7f7068a8ebbd55eb43795eefb4Chong Zhang } 717cabcaccabb00c7f7068a8ebbd55eb43795eefb4Chong Zhang int[] version = new int[2]; 727cabcaccabb00c7f7068a8ebbd55eb43795eefb4Chong Zhang if (!EGL14.eglInitialize(mEGLDisplay, version, 0, version, 1)) { 737cabcaccabb00c7f7068a8ebbd55eb43795eefb4Chong Zhang mEGLDisplay = null; 747cabcaccabb00c7f7068a8ebbd55eb43795eefb4Chong Zhang throw new RuntimeException("unable to initialize EGL14"); 757cabcaccabb00c7f7068a8ebbd55eb43795eefb4Chong Zhang } 767cabcaccabb00c7f7068a8ebbd55eb43795eefb4Chong Zhang 777cabcaccabb00c7f7068a8ebbd55eb43795eefb4Chong Zhang // Configure EGL for recordable and OpenGL ES 2.0. We want enough RGB bits 787cabcaccabb00c7f7068a8ebbd55eb43795eefb4Chong Zhang // to minimize artifacts from possible YUV conversion. 797cabcaccabb00c7f7068a8ebbd55eb43795eefb4Chong Zhang int[] attribList = { 807cabcaccabb00c7f7068a8ebbd55eb43795eefb4Chong Zhang EGL14.EGL_RED_SIZE, 8, 817cabcaccabb00c7f7068a8ebbd55eb43795eefb4Chong Zhang EGL14.EGL_GREEN_SIZE, 8, 827cabcaccabb00c7f7068a8ebbd55eb43795eefb4Chong Zhang EGL14.EGL_BLUE_SIZE, 8, 837cabcaccabb00c7f7068a8ebbd55eb43795eefb4Chong Zhang EGL14.EGL_RENDERABLE_TYPE, EGL14.EGL_OPENGL_ES2_BIT, 847cabcaccabb00c7f7068a8ebbd55eb43795eefb4Chong Zhang EGLExt.EGL_RECORDABLE_ANDROID, 1, 857cabcaccabb00c7f7068a8ebbd55eb43795eefb4Chong Zhang EGL14.EGL_NONE 867cabcaccabb00c7f7068a8ebbd55eb43795eefb4Chong Zhang }; 877cabcaccabb00c7f7068a8ebbd55eb43795eefb4Chong Zhang int[] numConfigs = new int[1]; 887cabcaccabb00c7f7068a8ebbd55eb43795eefb4Chong Zhang if (!EGL14.eglChooseConfig(mEGLDisplay, attribList, 0, mConfigs, 0, mConfigs.length, 897cabcaccabb00c7f7068a8ebbd55eb43795eefb4Chong Zhang numConfigs, 0)) { 907cabcaccabb00c7f7068a8ebbd55eb43795eefb4Chong Zhang throw new RuntimeException("unable to find RGB888+recordable ES2 EGL config"); 917cabcaccabb00c7f7068a8ebbd55eb43795eefb4Chong Zhang } 927cabcaccabb00c7f7068a8ebbd55eb43795eefb4Chong Zhang 937cabcaccabb00c7f7068a8ebbd55eb43795eefb4Chong Zhang // Configure context for OpenGL ES 2.0. 947cabcaccabb00c7f7068a8ebbd55eb43795eefb4Chong Zhang int[] attrib_list = { 957cabcaccabb00c7f7068a8ebbd55eb43795eefb4Chong Zhang EGL14.EGL_CONTEXT_CLIENT_VERSION, 2, 967cabcaccabb00c7f7068a8ebbd55eb43795eefb4Chong Zhang EGL14.EGL_NONE 977cabcaccabb00c7f7068a8ebbd55eb43795eefb4Chong Zhang }; 987cabcaccabb00c7f7068a8ebbd55eb43795eefb4Chong Zhang mEGLContext = EGL14.eglCreateContext(mEGLDisplay, mConfigs[0], EGL14.EGL_NO_CONTEXT, 997cabcaccabb00c7f7068a8ebbd55eb43795eefb4Chong Zhang attrib_list, 0); 1007cabcaccabb00c7f7068a8ebbd55eb43795eefb4Chong Zhang checkEglError("eglCreateContext"); 1017cabcaccabb00c7f7068a8ebbd55eb43795eefb4Chong Zhang if (mEGLContext == null) { 1027cabcaccabb00c7f7068a8ebbd55eb43795eefb4Chong Zhang throw new RuntimeException("null context"); 1037cabcaccabb00c7f7068a8ebbd55eb43795eefb4Chong Zhang } 1047cabcaccabb00c7f7068a8ebbd55eb43795eefb4Chong Zhang 1057cabcaccabb00c7f7068a8ebbd55eb43795eefb4Chong Zhang // Create a window surface, and attach it to the Surface we received. 1067cabcaccabb00c7f7068a8ebbd55eb43795eefb4Chong Zhang createEGLSurface(); 1077cabcaccabb00c7f7068a8ebbd55eb43795eefb4Chong Zhang 1087cabcaccabb00c7f7068a8ebbd55eb43795eefb4Chong Zhang mWidth = getWidth(); 1097cabcaccabb00c7f7068a8ebbd55eb43795eefb4Chong Zhang mHeight = getHeight(); 1107cabcaccabb00c7f7068a8ebbd55eb43795eefb4Chong Zhang } 1117cabcaccabb00c7f7068a8ebbd55eb43795eefb4Chong Zhang 1127cabcaccabb00c7f7068a8ebbd55eb43795eefb4Chong Zhang public void updateSize(int width, int height) { 1137cabcaccabb00c7f7068a8ebbd55eb43795eefb4Chong Zhang if (width != mWidth || height != mHeight) { 1147cabcaccabb00c7f7068a8ebbd55eb43795eefb4Chong Zhang Log.d(TAG, "re-create EGLSurface"); 1157cabcaccabb00c7f7068a8ebbd55eb43795eefb4Chong Zhang releaseEGLSurface(); 1167cabcaccabb00c7f7068a8ebbd55eb43795eefb4Chong Zhang createEGLSurface(); 1177cabcaccabb00c7f7068a8ebbd55eb43795eefb4Chong Zhang mWidth = getWidth(); 1187cabcaccabb00c7f7068a8ebbd55eb43795eefb4Chong Zhang mHeight = getHeight(); 1197cabcaccabb00c7f7068a8ebbd55eb43795eefb4Chong Zhang } 1207cabcaccabb00c7f7068a8ebbd55eb43795eefb4Chong Zhang } 1217cabcaccabb00c7f7068a8ebbd55eb43795eefb4Chong Zhang 1227cabcaccabb00c7f7068a8ebbd55eb43795eefb4Chong Zhang private void createEGLSurface() { 1237cabcaccabb00c7f7068a8ebbd55eb43795eefb4Chong Zhang int[] surfaceAttribs = { 1247cabcaccabb00c7f7068a8ebbd55eb43795eefb4Chong Zhang EGL14.EGL_NONE 1257cabcaccabb00c7f7068a8ebbd55eb43795eefb4Chong Zhang }; 1267cabcaccabb00c7f7068a8ebbd55eb43795eefb4Chong Zhang mEGLSurface = EGL14.eglCreateWindowSurface(mEGLDisplay, mConfigs[0], mSurface, 1277cabcaccabb00c7f7068a8ebbd55eb43795eefb4Chong Zhang surfaceAttribs, 0); 1287cabcaccabb00c7f7068a8ebbd55eb43795eefb4Chong Zhang checkEglError("eglCreateWindowSurface"); 1297cabcaccabb00c7f7068a8ebbd55eb43795eefb4Chong Zhang if (mEGLSurface == null) { 1307cabcaccabb00c7f7068a8ebbd55eb43795eefb4Chong Zhang throw new RuntimeException("surface was null"); 1317cabcaccabb00c7f7068a8ebbd55eb43795eefb4Chong Zhang } 1327cabcaccabb00c7f7068a8ebbd55eb43795eefb4Chong Zhang } 1337cabcaccabb00c7f7068a8ebbd55eb43795eefb4Chong Zhang 1347cabcaccabb00c7f7068a8ebbd55eb43795eefb4Chong Zhang private void releaseEGLSurface() { 135b1433f75d87710262b14824c98854a4865f98836Aurimas Liutikas if (!Objects.equals(mEGLDisplay, EGL14.EGL_NO_DISPLAY)) { 1367cabcaccabb00c7f7068a8ebbd55eb43795eefb4Chong Zhang EGL14.eglDestroySurface(mEGLDisplay, mEGLSurface); 1377cabcaccabb00c7f7068a8ebbd55eb43795eefb4Chong Zhang mEGLSurface = EGL14.EGL_NO_SURFACE; 1387cabcaccabb00c7f7068a8ebbd55eb43795eefb4Chong Zhang } 1397cabcaccabb00c7f7068a8ebbd55eb43795eefb4Chong Zhang } 1407cabcaccabb00c7f7068a8ebbd55eb43795eefb4Chong Zhang 1417cabcaccabb00c7f7068a8ebbd55eb43795eefb4Chong Zhang /** 1427cabcaccabb00c7f7068a8ebbd55eb43795eefb4Chong Zhang * Discard all resources held by this class, notably the EGL context. Also releases the 1437cabcaccabb00c7f7068a8ebbd55eb43795eefb4Chong Zhang * Surface that was passed to our constructor. 1447cabcaccabb00c7f7068a8ebbd55eb43795eefb4Chong Zhang */ 1457cabcaccabb00c7f7068a8ebbd55eb43795eefb4Chong Zhang public void release() { 146b1433f75d87710262b14824c98854a4865f98836Aurimas Liutikas if (!Objects.equals(mEGLDisplay, EGL14.EGL_NO_DISPLAY)) { 1477cabcaccabb00c7f7068a8ebbd55eb43795eefb4Chong Zhang EGL14.eglDestroySurface(mEGLDisplay, mEGLSurface); 1487cabcaccabb00c7f7068a8ebbd55eb43795eefb4Chong Zhang EGL14.eglDestroyContext(mEGLDisplay, mEGLContext); 1497cabcaccabb00c7f7068a8ebbd55eb43795eefb4Chong Zhang EGL14.eglReleaseThread(); 1507cabcaccabb00c7f7068a8ebbd55eb43795eefb4Chong Zhang EGL14.eglTerminate(mEGLDisplay); 1517cabcaccabb00c7f7068a8ebbd55eb43795eefb4Chong Zhang } 1527cabcaccabb00c7f7068a8ebbd55eb43795eefb4Chong Zhang 1537cabcaccabb00c7f7068a8ebbd55eb43795eefb4Chong Zhang mSurface.release(); 1547cabcaccabb00c7f7068a8ebbd55eb43795eefb4Chong Zhang 1557cabcaccabb00c7f7068a8ebbd55eb43795eefb4Chong Zhang mEGLDisplay = EGL14.EGL_NO_DISPLAY; 1567cabcaccabb00c7f7068a8ebbd55eb43795eefb4Chong Zhang mEGLContext = EGL14.EGL_NO_CONTEXT; 1577cabcaccabb00c7f7068a8ebbd55eb43795eefb4Chong Zhang mEGLSurface = EGL14.EGL_NO_SURFACE; 1587cabcaccabb00c7f7068a8ebbd55eb43795eefb4Chong Zhang 1597cabcaccabb00c7f7068a8ebbd55eb43795eefb4Chong Zhang mSurface = null; 1607cabcaccabb00c7f7068a8ebbd55eb43795eefb4Chong Zhang } 1617cabcaccabb00c7f7068a8ebbd55eb43795eefb4Chong Zhang 1627cabcaccabb00c7f7068a8ebbd55eb43795eefb4Chong Zhang /** 1637cabcaccabb00c7f7068a8ebbd55eb43795eefb4Chong Zhang * Makes our EGL context and surface current. 1647cabcaccabb00c7f7068a8ebbd55eb43795eefb4Chong Zhang */ 1657cabcaccabb00c7f7068a8ebbd55eb43795eefb4Chong Zhang public void makeCurrent() { 1667cabcaccabb00c7f7068a8ebbd55eb43795eefb4Chong Zhang if (!EGL14.eglMakeCurrent(mEGLDisplay, mEGLSurface, mEGLSurface, mEGLContext)) { 1677cabcaccabb00c7f7068a8ebbd55eb43795eefb4Chong Zhang throw new RuntimeException("eglMakeCurrent failed"); 1687cabcaccabb00c7f7068a8ebbd55eb43795eefb4Chong Zhang } 1697cabcaccabb00c7f7068a8ebbd55eb43795eefb4Chong Zhang } 1707cabcaccabb00c7f7068a8ebbd55eb43795eefb4Chong Zhang 1717cabcaccabb00c7f7068a8ebbd55eb43795eefb4Chong Zhang /** 1727cabcaccabb00c7f7068a8ebbd55eb43795eefb4Chong Zhang * Makes our EGL context and surface not current. 1737cabcaccabb00c7f7068a8ebbd55eb43795eefb4Chong Zhang */ 1747cabcaccabb00c7f7068a8ebbd55eb43795eefb4Chong Zhang public void makeUnCurrent() { 1757cabcaccabb00c7f7068a8ebbd55eb43795eefb4Chong Zhang if (!EGL14.eglMakeCurrent(mEGLDisplay, EGL14.EGL_NO_SURFACE, EGL14.EGL_NO_SURFACE, 1767cabcaccabb00c7f7068a8ebbd55eb43795eefb4Chong Zhang EGL14.EGL_NO_CONTEXT)) { 1777cabcaccabb00c7f7068a8ebbd55eb43795eefb4Chong Zhang throw new RuntimeException("eglMakeCurrent failed"); 1787cabcaccabb00c7f7068a8ebbd55eb43795eefb4Chong Zhang } 1797cabcaccabb00c7f7068a8ebbd55eb43795eefb4Chong Zhang } 1807cabcaccabb00c7f7068a8ebbd55eb43795eefb4Chong Zhang 1817cabcaccabb00c7f7068a8ebbd55eb43795eefb4Chong Zhang /** 1827cabcaccabb00c7f7068a8ebbd55eb43795eefb4Chong Zhang * Calls eglSwapBuffers. Use this to "publish" the current frame. 1837cabcaccabb00c7f7068a8ebbd55eb43795eefb4Chong Zhang */ 1847cabcaccabb00c7f7068a8ebbd55eb43795eefb4Chong Zhang public boolean swapBuffers() { 1857cabcaccabb00c7f7068a8ebbd55eb43795eefb4Chong Zhang return EGL14.eglSwapBuffers(mEGLDisplay, mEGLSurface); 1867cabcaccabb00c7f7068a8ebbd55eb43795eefb4Chong Zhang } 1877cabcaccabb00c7f7068a8ebbd55eb43795eefb4Chong Zhang 1887cabcaccabb00c7f7068a8ebbd55eb43795eefb4Chong Zhang /** 1897cabcaccabb00c7f7068a8ebbd55eb43795eefb4Chong Zhang * Returns the Surface that the MediaCodec receives buffers from. 1907cabcaccabb00c7f7068a8ebbd55eb43795eefb4Chong Zhang */ 1917cabcaccabb00c7f7068a8ebbd55eb43795eefb4Chong Zhang public Surface getSurface() { 1927cabcaccabb00c7f7068a8ebbd55eb43795eefb4Chong Zhang return mSurface; 1937cabcaccabb00c7f7068a8ebbd55eb43795eefb4Chong Zhang } 1947cabcaccabb00c7f7068a8ebbd55eb43795eefb4Chong Zhang 1957cabcaccabb00c7f7068a8ebbd55eb43795eefb4Chong Zhang /** 1967cabcaccabb00c7f7068a8ebbd55eb43795eefb4Chong Zhang * Queries the surface's width. 1977cabcaccabb00c7f7068a8ebbd55eb43795eefb4Chong Zhang */ 1987cabcaccabb00c7f7068a8ebbd55eb43795eefb4Chong Zhang public int getWidth() { 1997cabcaccabb00c7f7068a8ebbd55eb43795eefb4Chong Zhang int[] value = new int[1]; 2007cabcaccabb00c7f7068a8ebbd55eb43795eefb4Chong Zhang EGL14.eglQuerySurface(mEGLDisplay, mEGLSurface, EGL14.EGL_WIDTH, value, 0); 2017cabcaccabb00c7f7068a8ebbd55eb43795eefb4Chong Zhang return value[0]; 2027cabcaccabb00c7f7068a8ebbd55eb43795eefb4Chong Zhang } 2037cabcaccabb00c7f7068a8ebbd55eb43795eefb4Chong Zhang 2047cabcaccabb00c7f7068a8ebbd55eb43795eefb4Chong Zhang /** 2057cabcaccabb00c7f7068a8ebbd55eb43795eefb4Chong Zhang * Queries the surface's height. 2067cabcaccabb00c7f7068a8ebbd55eb43795eefb4Chong Zhang */ 2077cabcaccabb00c7f7068a8ebbd55eb43795eefb4Chong Zhang public int getHeight() { 2087cabcaccabb00c7f7068a8ebbd55eb43795eefb4Chong Zhang int[] value = new int[1]; 2097cabcaccabb00c7f7068a8ebbd55eb43795eefb4Chong Zhang EGL14.eglQuerySurface(mEGLDisplay, mEGLSurface, EGL14.EGL_HEIGHT, value, 0); 2107cabcaccabb00c7f7068a8ebbd55eb43795eefb4Chong Zhang return value[0]; 2117cabcaccabb00c7f7068a8ebbd55eb43795eefb4Chong Zhang } 2127cabcaccabb00c7f7068a8ebbd55eb43795eefb4Chong Zhang 2137cabcaccabb00c7f7068a8ebbd55eb43795eefb4Chong Zhang /** 2147cabcaccabb00c7f7068a8ebbd55eb43795eefb4Chong Zhang * Sends the presentation time stamp to EGL. Time is expressed in nanoseconds. 2157cabcaccabb00c7f7068a8ebbd55eb43795eefb4Chong Zhang */ 2167cabcaccabb00c7f7068a8ebbd55eb43795eefb4Chong Zhang public void setPresentationTime(long nsecs) { 2177cabcaccabb00c7f7068a8ebbd55eb43795eefb4Chong Zhang EGLExt.eglPresentationTimeANDROID(mEGLDisplay, mEGLSurface, nsecs); 2187cabcaccabb00c7f7068a8ebbd55eb43795eefb4Chong Zhang } 2197cabcaccabb00c7f7068a8ebbd55eb43795eefb4Chong Zhang 2207cabcaccabb00c7f7068a8ebbd55eb43795eefb4Chong Zhang /** 2217cabcaccabb00c7f7068a8ebbd55eb43795eefb4Chong Zhang * Checks for EGL errors. 2227cabcaccabb00c7f7068a8ebbd55eb43795eefb4Chong Zhang */ 2237cabcaccabb00c7f7068a8ebbd55eb43795eefb4Chong Zhang private void checkEglError(String msg) { 2247cabcaccabb00c7f7068a8ebbd55eb43795eefb4Chong Zhang int error; 2257cabcaccabb00c7f7068a8ebbd55eb43795eefb4Chong Zhang if ((error = EGL14.eglGetError()) != EGL14.EGL_SUCCESS) { 2267cabcaccabb00c7f7068a8ebbd55eb43795eefb4Chong Zhang throw new RuntimeException(msg + ": EGL error: 0x" + Integer.toHexString(error)); 2277cabcaccabb00c7f7068a8ebbd55eb43795eefb4Chong Zhang } 2287cabcaccabb00c7f7068a8ebbd55eb43795eefb4Chong Zhang } 2297cabcaccabb00c7f7068a8ebbd55eb43795eefb4Chong Zhang} 230