EglWindow.cpp revision 441e847feb0e055ecb004802802cea07782ab228
1/* 2 * Copyright 2013 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 17#define LOG_TAG "ScreenRecord" 18//#define LOG_NDEBUG 0 19#include <utils/Log.h> 20 21#define EGL_EGLEXT_PROTOTYPES 22 23#include <gui/BufferQueue.h> 24#include <gui/GraphicBufferAlloc.h> 25#include <gui/Surface.h> 26 27#include "EglWindow.h" 28 29#include <EGL/egl.h> 30#include <EGL/eglext.h> 31 32#include <assert.h> 33 34using namespace android; 35 36 37status_t EglWindow::createWindow(const sp<IGraphicBufferProducer>& surface) { 38 status_t err = eglSetupContext(); 39 if (err != NO_ERROR) { 40 return err; 41 } 42 43 surface->query(NATIVE_WINDOW_WIDTH, &mWidth); 44 surface->query(NATIVE_WINDOW_HEIGHT, &mHeight); 45 46 // Output side (EGL surface to draw on). 47 sp<ANativeWindow> anw = new Surface(surface); 48 mEglSurface = eglCreateWindowSurface(mEglDisplay, mEglConfig, anw.get(), 49 NULL); 50 if (mEglSurface == EGL_NO_SURFACE) { 51 ALOGE("eglCreateWindowSurface error: %#x", eglGetError()); 52 eglRelease(); 53 return UNKNOWN_ERROR; 54 } 55 56 return NO_ERROR; 57} 58 59status_t EglWindow::makeCurrent() const { 60 if (!eglMakeCurrent(mEglDisplay, mEglSurface, mEglSurface, mEglContext)) { 61 ALOGE("eglMakeCurrent failed: %#x", eglGetError()); 62 return UNKNOWN_ERROR; 63 } 64 return NO_ERROR; 65} 66 67status_t EglWindow::eglSetupContext() { 68 EGLBoolean result; 69 70 mEglDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY); 71 if (mEglDisplay == EGL_NO_DISPLAY) { 72 ALOGE("eglGetDisplay failed: %#x", eglGetError()); 73 return UNKNOWN_ERROR; 74 } 75 76 EGLint majorVersion, minorVersion; 77 result = eglInitialize(mEglDisplay, &majorVersion, &minorVersion); 78 if (result != EGL_TRUE) { 79 ALOGE("eglInitialize failed: %#x", eglGetError()); 80 return UNKNOWN_ERROR; 81 } 82 ALOGV("Initialized EGL v%d.%d", majorVersion, minorVersion); 83 84 EGLint numConfigs = 0; 85 EGLint configAttribs[] = { 86 EGL_SURFACE_TYPE, EGL_WINDOW_BIT, 87 EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT, 88 EGL_RECORDABLE_ANDROID, 1, 89 EGL_RED_SIZE, 8, 90 EGL_GREEN_SIZE, 8, 91 EGL_BLUE_SIZE, 8, 92 EGL_NONE 93 }; 94 result = eglChooseConfig(mEglDisplay, configAttribs, &mEglConfig, 1, 95 &numConfigs); 96 if (result != EGL_TRUE) { 97 ALOGE("eglChooseConfig error: %#x", eglGetError()); 98 return UNKNOWN_ERROR; 99 } 100 101 EGLint contextAttribs[] = { 102 EGL_CONTEXT_CLIENT_VERSION, 2, 103 EGL_NONE 104 }; 105 mEglContext = eglCreateContext(mEglDisplay, mEglConfig, EGL_NO_CONTEXT, 106 contextAttribs); 107 if (mEglContext == EGL_NO_CONTEXT) { 108 ALOGE("eglCreateContext error: %#x", eglGetError()); 109 return UNKNOWN_ERROR; 110 } 111 112 return NO_ERROR; 113} 114 115void EglWindow::eglRelease() { 116 ALOGV("EglWindow::eglRelease"); 117 if (mEglDisplay != EGL_NO_DISPLAY) { 118 eglMakeCurrent(mEglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, 119 EGL_NO_CONTEXT); 120 121 if (mEglContext != EGL_NO_CONTEXT) { 122 eglDestroyContext(mEglDisplay, mEglContext); 123 } 124 125 if (mEglSurface != EGL_NO_SURFACE) { 126 eglDestroySurface(mEglDisplay, mEglSurface); 127 } 128 } 129 130 mEglDisplay = EGL_NO_DISPLAY; 131 mEglContext = EGL_NO_CONTEXT; 132 mEglSurface = EGL_NO_SURFACE; 133 mEglConfig = NULL; 134 135 eglReleaseThread(); 136} 137 138// Sets the presentation time on the current EGL buffer. 139void EglWindow::presentationTime(nsecs_t whenNsec) const { 140 eglPresentationTimeANDROID(mEglDisplay, mEglSurface, whenNsec); 141} 142 143// Swaps the EGL buffer. 144void EglWindow::swapBuffers() const { 145 eglSwapBuffers(mEglDisplay, mEglSurface); 146} 147