1441e847feb0e055ecb004802802cea07782ab228Andy McFadden/* 2441e847feb0e055ecb004802802cea07782ab228Andy McFadden * Copyright 2013 The Android Open Source Project 3441e847feb0e055ecb004802802cea07782ab228Andy McFadden * 4441e847feb0e055ecb004802802cea07782ab228Andy McFadden * Licensed under the Apache License, Version 2.0 (the "License"); 5441e847feb0e055ecb004802802cea07782ab228Andy McFadden * you may not use this file except in compliance with the License. 6441e847feb0e055ecb004802802cea07782ab228Andy McFadden * You may obtain a copy of the License at 7441e847feb0e055ecb004802802cea07782ab228Andy McFadden * 8441e847feb0e055ecb004802802cea07782ab228Andy McFadden * http://www.apache.org/licenses/LICENSE-2.0 9441e847feb0e055ecb004802802cea07782ab228Andy McFadden * 10441e847feb0e055ecb004802802cea07782ab228Andy McFadden * Unless required by applicable law or agreed to in writing, software 11441e847feb0e055ecb004802802cea07782ab228Andy McFadden * distributed under the License is distributed on an "AS IS" BASIS, 12441e847feb0e055ecb004802802cea07782ab228Andy McFadden * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13441e847feb0e055ecb004802802cea07782ab228Andy McFadden * See the License for the specific language governing permissions and 14441e847feb0e055ecb004802802cea07782ab228Andy McFadden * limitations under the License. 15441e847feb0e055ecb004802802cea07782ab228Andy McFadden */ 16441e847feb0e055ecb004802802cea07782ab228Andy McFadden 17441e847feb0e055ecb004802802cea07782ab228Andy McFadden#define LOG_TAG "ScreenRecord" 18441e847feb0e055ecb004802802cea07782ab228Andy McFadden//#define LOG_NDEBUG 0 19441e847feb0e055ecb004802802cea07782ab228Andy McFadden#include <utils/Log.h> 20441e847feb0e055ecb004802802cea07782ab228Andy McFadden 21441e847feb0e055ecb004802802cea07782ab228Andy McFadden#define EGL_EGLEXT_PROTOTYPES 22441e847feb0e055ecb004802802cea07782ab228Andy McFadden 23441e847feb0e055ecb004802802cea07782ab228Andy McFadden#include <gui/BufferQueue.h> 24441e847feb0e055ecb004802802cea07782ab228Andy McFadden#include <gui/GraphicBufferAlloc.h> 25441e847feb0e055ecb004802802cea07782ab228Andy McFadden#include <gui/Surface.h> 26441e847feb0e055ecb004802802cea07782ab228Andy McFadden 27441e847feb0e055ecb004802802cea07782ab228Andy McFadden#include "EglWindow.h" 28441e847feb0e055ecb004802802cea07782ab228Andy McFadden 29441e847feb0e055ecb004802802cea07782ab228Andy McFadden#include <EGL/egl.h> 30441e847feb0e055ecb004802802cea07782ab228Andy McFadden#include <EGL/eglext.h> 31441e847feb0e055ecb004802802cea07782ab228Andy McFadden 32441e847feb0e055ecb004802802cea07782ab228Andy McFadden#include <assert.h> 33441e847feb0e055ecb004802802cea07782ab228Andy McFadden 34441e847feb0e055ecb004802802cea07782ab228Andy McFaddenusing namespace android; 35441e847feb0e055ecb004802802cea07782ab228Andy McFadden 36441e847feb0e055ecb004802802cea07782ab228Andy McFadden 37441e847feb0e055ecb004802802cea07782ab228Andy McFaddenstatus_t EglWindow::createWindow(const sp<IGraphicBufferProducer>& surface) { 38587c6fefcd3c1d05c608ff511cf3534bc765256eAndy McFadden if (mEglSurface != EGL_NO_SURFACE) { 39587c6fefcd3c1d05c608ff511cf3534bc765256eAndy McFadden ALOGE("surface already created"); 40587c6fefcd3c1d05c608ff511cf3534bc765256eAndy McFadden return UNKNOWN_ERROR; 41587c6fefcd3c1d05c608ff511cf3534bc765256eAndy McFadden } 42587c6fefcd3c1d05c608ff511cf3534bc765256eAndy McFadden status_t err = eglSetupContext(false); 43441e847feb0e055ecb004802802cea07782ab228Andy McFadden if (err != NO_ERROR) { 44441e847feb0e055ecb004802802cea07782ab228Andy McFadden return err; 45441e847feb0e055ecb004802802cea07782ab228Andy McFadden } 46441e847feb0e055ecb004802802cea07782ab228Andy McFadden 47587c6fefcd3c1d05c608ff511cf3534bc765256eAndy McFadden // Cache the current dimensions. We're not expecting these to change. 48441e847feb0e055ecb004802802cea07782ab228Andy McFadden surface->query(NATIVE_WINDOW_WIDTH, &mWidth); 49441e847feb0e055ecb004802802cea07782ab228Andy McFadden surface->query(NATIVE_WINDOW_HEIGHT, &mHeight); 50441e847feb0e055ecb004802802cea07782ab228Andy McFadden 51441e847feb0e055ecb004802802cea07782ab228Andy McFadden // Output side (EGL surface to draw on). 52441e847feb0e055ecb004802802cea07782ab228Andy McFadden sp<ANativeWindow> anw = new Surface(surface); 53441e847feb0e055ecb004802802cea07782ab228Andy McFadden mEglSurface = eglCreateWindowSurface(mEglDisplay, mEglConfig, anw.get(), 54441e847feb0e055ecb004802802cea07782ab228Andy McFadden NULL); 55441e847feb0e055ecb004802802cea07782ab228Andy McFadden if (mEglSurface == EGL_NO_SURFACE) { 56441e847feb0e055ecb004802802cea07782ab228Andy McFadden ALOGE("eglCreateWindowSurface error: %#x", eglGetError()); 57441e847feb0e055ecb004802802cea07782ab228Andy McFadden eglRelease(); 58441e847feb0e055ecb004802802cea07782ab228Andy McFadden return UNKNOWN_ERROR; 59441e847feb0e055ecb004802802cea07782ab228Andy McFadden } 60441e847feb0e055ecb004802802cea07782ab228Andy McFadden 61441e847feb0e055ecb004802802cea07782ab228Andy McFadden return NO_ERROR; 62441e847feb0e055ecb004802802cea07782ab228Andy McFadden} 63441e847feb0e055ecb004802802cea07782ab228Andy McFadden 64587c6fefcd3c1d05c608ff511cf3534bc765256eAndy McFaddenstatus_t EglWindow::createPbuffer(int width, int height) { 65587c6fefcd3c1d05c608ff511cf3534bc765256eAndy McFadden if (mEglSurface != EGL_NO_SURFACE) { 66587c6fefcd3c1d05c608ff511cf3534bc765256eAndy McFadden ALOGE("surface already created"); 67587c6fefcd3c1d05c608ff511cf3534bc765256eAndy McFadden return UNKNOWN_ERROR; 68587c6fefcd3c1d05c608ff511cf3534bc765256eAndy McFadden } 69587c6fefcd3c1d05c608ff511cf3534bc765256eAndy McFadden status_t err = eglSetupContext(true); 70587c6fefcd3c1d05c608ff511cf3534bc765256eAndy McFadden if (err != NO_ERROR) { 71587c6fefcd3c1d05c608ff511cf3534bc765256eAndy McFadden return err; 72587c6fefcd3c1d05c608ff511cf3534bc765256eAndy McFadden } 73587c6fefcd3c1d05c608ff511cf3534bc765256eAndy McFadden 74587c6fefcd3c1d05c608ff511cf3534bc765256eAndy McFadden mWidth = width; 75587c6fefcd3c1d05c608ff511cf3534bc765256eAndy McFadden mHeight = height; 76587c6fefcd3c1d05c608ff511cf3534bc765256eAndy McFadden 77587c6fefcd3c1d05c608ff511cf3534bc765256eAndy McFadden EGLint pbufferAttribs[] = { 78587c6fefcd3c1d05c608ff511cf3534bc765256eAndy McFadden EGL_WIDTH, width, 79587c6fefcd3c1d05c608ff511cf3534bc765256eAndy McFadden EGL_HEIGHT, height, 80587c6fefcd3c1d05c608ff511cf3534bc765256eAndy McFadden EGL_NONE 81587c6fefcd3c1d05c608ff511cf3534bc765256eAndy McFadden }; 82587c6fefcd3c1d05c608ff511cf3534bc765256eAndy McFadden mEglSurface = eglCreatePbufferSurface(mEglDisplay, mEglConfig, pbufferAttribs); 83587c6fefcd3c1d05c608ff511cf3534bc765256eAndy McFadden if (mEglSurface == EGL_NO_SURFACE) { 84587c6fefcd3c1d05c608ff511cf3534bc765256eAndy McFadden ALOGE("eglCreatePbufferSurface error: %#x", eglGetError()); 85587c6fefcd3c1d05c608ff511cf3534bc765256eAndy McFadden eglRelease(); 86587c6fefcd3c1d05c608ff511cf3534bc765256eAndy McFadden return UNKNOWN_ERROR; 87587c6fefcd3c1d05c608ff511cf3534bc765256eAndy McFadden } 88587c6fefcd3c1d05c608ff511cf3534bc765256eAndy McFadden 89587c6fefcd3c1d05c608ff511cf3534bc765256eAndy McFadden return NO_ERROR; 90587c6fefcd3c1d05c608ff511cf3534bc765256eAndy McFadden} 91587c6fefcd3c1d05c608ff511cf3534bc765256eAndy McFadden 92441e847feb0e055ecb004802802cea07782ab228Andy McFaddenstatus_t EglWindow::makeCurrent() const { 93441e847feb0e055ecb004802802cea07782ab228Andy McFadden if (!eglMakeCurrent(mEglDisplay, mEglSurface, mEglSurface, mEglContext)) { 94441e847feb0e055ecb004802802cea07782ab228Andy McFadden ALOGE("eglMakeCurrent failed: %#x", eglGetError()); 95441e847feb0e055ecb004802802cea07782ab228Andy McFadden return UNKNOWN_ERROR; 96441e847feb0e055ecb004802802cea07782ab228Andy McFadden } 97441e847feb0e055ecb004802802cea07782ab228Andy McFadden return NO_ERROR; 98441e847feb0e055ecb004802802cea07782ab228Andy McFadden} 99441e847feb0e055ecb004802802cea07782ab228Andy McFadden 100587c6fefcd3c1d05c608ff511cf3534bc765256eAndy McFaddenstatus_t EglWindow::eglSetupContext(bool forPbuffer) { 101441e847feb0e055ecb004802802cea07782ab228Andy McFadden EGLBoolean result; 102441e847feb0e055ecb004802802cea07782ab228Andy McFadden 103441e847feb0e055ecb004802802cea07782ab228Andy McFadden mEglDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY); 104441e847feb0e055ecb004802802cea07782ab228Andy McFadden if (mEglDisplay == EGL_NO_DISPLAY) { 105441e847feb0e055ecb004802802cea07782ab228Andy McFadden ALOGE("eglGetDisplay failed: %#x", eglGetError()); 106441e847feb0e055ecb004802802cea07782ab228Andy McFadden return UNKNOWN_ERROR; 107441e847feb0e055ecb004802802cea07782ab228Andy McFadden } 108441e847feb0e055ecb004802802cea07782ab228Andy McFadden 109441e847feb0e055ecb004802802cea07782ab228Andy McFadden EGLint majorVersion, minorVersion; 110441e847feb0e055ecb004802802cea07782ab228Andy McFadden result = eglInitialize(mEglDisplay, &majorVersion, &minorVersion); 111441e847feb0e055ecb004802802cea07782ab228Andy McFadden if (result != EGL_TRUE) { 112441e847feb0e055ecb004802802cea07782ab228Andy McFadden ALOGE("eglInitialize failed: %#x", eglGetError()); 113441e847feb0e055ecb004802802cea07782ab228Andy McFadden return UNKNOWN_ERROR; 114441e847feb0e055ecb004802802cea07782ab228Andy McFadden } 115441e847feb0e055ecb004802802cea07782ab228Andy McFadden ALOGV("Initialized EGL v%d.%d", majorVersion, minorVersion); 116441e847feb0e055ecb004802802cea07782ab228Andy McFadden 117441e847feb0e055ecb004802802cea07782ab228Andy McFadden EGLint numConfigs = 0; 118587c6fefcd3c1d05c608ff511cf3534bc765256eAndy McFadden EGLint windowConfigAttribs[] = { 119587c6fefcd3c1d05c608ff511cf3534bc765256eAndy McFadden EGL_SURFACE_TYPE, EGL_WINDOW_BIT, 120587c6fefcd3c1d05c608ff511cf3534bc765256eAndy McFadden EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT, 121587c6fefcd3c1d05c608ff511cf3534bc765256eAndy McFadden EGL_RECORDABLE_ANDROID, 1, 122587c6fefcd3c1d05c608ff511cf3534bc765256eAndy McFadden EGL_RED_SIZE, 8, 123587c6fefcd3c1d05c608ff511cf3534bc765256eAndy McFadden EGL_GREEN_SIZE, 8, 124587c6fefcd3c1d05c608ff511cf3534bc765256eAndy McFadden EGL_BLUE_SIZE, 8, 125587c6fefcd3c1d05c608ff511cf3534bc765256eAndy McFadden // no alpha 126587c6fefcd3c1d05c608ff511cf3534bc765256eAndy McFadden EGL_NONE 127587c6fefcd3c1d05c608ff511cf3534bc765256eAndy McFadden }; 128587c6fefcd3c1d05c608ff511cf3534bc765256eAndy McFadden EGLint pbufferConfigAttribs[] = { 129587c6fefcd3c1d05c608ff511cf3534bc765256eAndy McFadden EGL_SURFACE_TYPE, EGL_PBUFFER_BIT, 130587c6fefcd3c1d05c608ff511cf3534bc765256eAndy McFadden EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT, 131587c6fefcd3c1d05c608ff511cf3534bc765256eAndy McFadden EGL_RED_SIZE, 8, 132587c6fefcd3c1d05c608ff511cf3534bc765256eAndy McFadden EGL_GREEN_SIZE, 8, 133587c6fefcd3c1d05c608ff511cf3534bc765256eAndy McFadden EGL_BLUE_SIZE, 8, 134587c6fefcd3c1d05c608ff511cf3534bc765256eAndy McFadden EGL_ALPHA_SIZE, 8, 135587c6fefcd3c1d05c608ff511cf3534bc765256eAndy McFadden EGL_NONE 136441e847feb0e055ecb004802802cea07782ab228Andy McFadden }; 137587c6fefcd3c1d05c608ff511cf3534bc765256eAndy McFadden result = eglChooseConfig(mEglDisplay, 138587c6fefcd3c1d05c608ff511cf3534bc765256eAndy McFadden forPbuffer ? pbufferConfigAttribs : windowConfigAttribs, 139587c6fefcd3c1d05c608ff511cf3534bc765256eAndy McFadden &mEglConfig, 1, &numConfigs); 140441e847feb0e055ecb004802802cea07782ab228Andy McFadden if (result != EGL_TRUE) { 141441e847feb0e055ecb004802802cea07782ab228Andy McFadden ALOGE("eglChooseConfig error: %#x", eglGetError()); 142441e847feb0e055ecb004802802cea07782ab228Andy McFadden return UNKNOWN_ERROR; 143441e847feb0e055ecb004802802cea07782ab228Andy McFadden } 144441e847feb0e055ecb004802802cea07782ab228Andy McFadden 145441e847feb0e055ecb004802802cea07782ab228Andy McFadden EGLint contextAttribs[] = { 146441e847feb0e055ecb004802802cea07782ab228Andy McFadden EGL_CONTEXT_CLIENT_VERSION, 2, 147441e847feb0e055ecb004802802cea07782ab228Andy McFadden EGL_NONE 148441e847feb0e055ecb004802802cea07782ab228Andy McFadden }; 149441e847feb0e055ecb004802802cea07782ab228Andy McFadden mEglContext = eglCreateContext(mEglDisplay, mEglConfig, EGL_NO_CONTEXT, 150441e847feb0e055ecb004802802cea07782ab228Andy McFadden contextAttribs); 151441e847feb0e055ecb004802802cea07782ab228Andy McFadden if (mEglContext == EGL_NO_CONTEXT) { 152441e847feb0e055ecb004802802cea07782ab228Andy McFadden ALOGE("eglCreateContext error: %#x", eglGetError()); 153441e847feb0e055ecb004802802cea07782ab228Andy McFadden return UNKNOWN_ERROR; 154441e847feb0e055ecb004802802cea07782ab228Andy McFadden } 155441e847feb0e055ecb004802802cea07782ab228Andy McFadden 156441e847feb0e055ecb004802802cea07782ab228Andy McFadden return NO_ERROR; 157441e847feb0e055ecb004802802cea07782ab228Andy McFadden} 158441e847feb0e055ecb004802802cea07782ab228Andy McFadden 159441e847feb0e055ecb004802802cea07782ab228Andy McFaddenvoid EglWindow::eglRelease() { 160441e847feb0e055ecb004802802cea07782ab228Andy McFadden ALOGV("EglWindow::eglRelease"); 161441e847feb0e055ecb004802802cea07782ab228Andy McFadden if (mEglDisplay != EGL_NO_DISPLAY) { 162441e847feb0e055ecb004802802cea07782ab228Andy McFadden eglMakeCurrent(mEglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, 163441e847feb0e055ecb004802802cea07782ab228Andy McFadden EGL_NO_CONTEXT); 164441e847feb0e055ecb004802802cea07782ab228Andy McFadden 165441e847feb0e055ecb004802802cea07782ab228Andy McFadden if (mEglContext != EGL_NO_CONTEXT) { 166441e847feb0e055ecb004802802cea07782ab228Andy McFadden eglDestroyContext(mEglDisplay, mEglContext); 167441e847feb0e055ecb004802802cea07782ab228Andy McFadden } 168441e847feb0e055ecb004802802cea07782ab228Andy McFadden 169441e847feb0e055ecb004802802cea07782ab228Andy McFadden if (mEglSurface != EGL_NO_SURFACE) { 170441e847feb0e055ecb004802802cea07782ab228Andy McFadden eglDestroySurface(mEglDisplay, mEglSurface); 171441e847feb0e055ecb004802802cea07782ab228Andy McFadden } 172441e847feb0e055ecb004802802cea07782ab228Andy McFadden } 173441e847feb0e055ecb004802802cea07782ab228Andy McFadden 174441e847feb0e055ecb004802802cea07782ab228Andy McFadden mEglDisplay = EGL_NO_DISPLAY; 175441e847feb0e055ecb004802802cea07782ab228Andy McFadden mEglContext = EGL_NO_CONTEXT; 176441e847feb0e055ecb004802802cea07782ab228Andy McFadden mEglSurface = EGL_NO_SURFACE; 177441e847feb0e055ecb004802802cea07782ab228Andy McFadden mEglConfig = NULL; 178441e847feb0e055ecb004802802cea07782ab228Andy McFadden 179441e847feb0e055ecb004802802cea07782ab228Andy McFadden eglReleaseThread(); 180441e847feb0e055ecb004802802cea07782ab228Andy McFadden} 181441e847feb0e055ecb004802802cea07782ab228Andy McFadden 182441e847feb0e055ecb004802802cea07782ab228Andy McFadden// Sets the presentation time on the current EGL buffer. 183441e847feb0e055ecb004802802cea07782ab228Andy McFaddenvoid EglWindow::presentationTime(nsecs_t whenNsec) const { 184441e847feb0e055ecb004802802cea07782ab228Andy McFadden eglPresentationTimeANDROID(mEglDisplay, mEglSurface, whenNsec); 185441e847feb0e055ecb004802802cea07782ab228Andy McFadden} 186441e847feb0e055ecb004802802cea07782ab228Andy McFadden 187441e847feb0e055ecb004802802cea07782ab228Andy McFadden// Swaps the EGL buffer. 188441e847feb0e055ecb004802802cea07782ab228Andy McFaddenvoid EglWindow::swapBuffers() const { 189441e847feb0e055ecb004802802cea07782ab228Andy McFadden eglSwapBuffers(mEglDisplay, mEglSurface); 190441e847feb0e055ecb004802802cea07782ab228Andy McFadden} 191