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/Surface.h> 25441e847feb0e055ecb004802802cea07782ab228Andy McFadden 26441e847feb0e055ecb004802802cea07782ab228Andy McFadden#include "EglWindow.h" 27441e847feb0e055ecb004802802cea07782ab228Andy McFadden 28441e847feb0e055ecb004802802cea07782ab228Andy McFadden#include <EGL/egl.h> 29441e847feb0e055ecb004802802cea07782ab228Andy McFadden#include <EGL/eglext.h> 30441e847feb0e055ecb004802802cea07782ab228Andy McFadden 31441e847feb0e055ecb004802802cea07782ab228Andy McFadden#include <assert.h> 32441e847feb0e055ecb004802802cea07782ab228Andy McFadden 33441e847feb0e055ecb004802802cea07782ab228Andy McFaddenusing namespace android; 34441e847feb0e055ecb004802802cea07782ab228Andy McFadden 35441e847feb0e055ecb004802802cea07782ab228Andy McFadden 36441e847feb0e055ecb004802802cea07782ab228Andy McFaddenstatus_t EglWindow::createWindow(const sp<IGraphicBufferProducer>& surface) { 37587c6fefcd3c1d05c608ff511cf3534bc765256eAndy McFadden if (mEglSurface != EGL_NO_SURFACE) { 38587c6fefcd3c1d05c608ff511cf3534bc765256eAndy McFadden ALOGE("surface already created"); 39587c6fefcd3c1d05c608ff511cf3534bc765256eAndy McFadden return UNKNOWN_ERROR; 40587c6fefcd3c1d05c608ff511cf3534bc765256eAndy McFadden } 41587c6fefcd3c1d05c608ff511cf3534bc765256eAndy McFadden status_t err = eglSetupContext(false); 42441e847feb0e055ecb004802802cea07782ab228Andy McFadden if (err != NO_ERROR) { 43441e847feb0e055ecb004802802cea07782ab228Andy McFadden return err; 44441e847feb0e055ecb004802802cea07782ab228Andy McFadden } 45441e847feb0e055ecb004802802cea07782ab228Andy McFadden 46587c6fefcd3c1d05c608ff511cf3534bc765256eAndy McFadden // Cache the current dimensions. We're not expecting these to change. 47441e847feb0e055ecb004802802cea07782ab228Andy McFadden surface->query(NATIVE_WINDOW_WIDTH, &mWidth); 48441e847feb0e055ecb004802802cea07782ab228Andy McFadden surface->query(NATIVE_WINDOW_HEIGHT, &mHeight); 49441e847feb0e055ecb004802802cea07782ab228Andy McFadden 50441e847feb0e055ecb004802802cea07782ab228Andy McFadden // Output side (EGL surface to draw on). 51441e847feb0e055ecb004802802cea07782ab228Andy McFadden sp<ANativeWindow> anw = new Surface(surface); 52441e847feb0e055ecb004802802cea07782ab228Andy McFadden mEglSurface = eglCreateWindowSurface(mEglDisplay, mEglConfig, anw.get(), 53441e847feb0e055ecb004802802cea07782ab228Andy McFadden NULL); 54441e847feb0e055ecb004802802cea07782ab228Andy McFadden if (mEglSurface == EGL_NO_SURFACE) { 55441e847feb0e055ecb004802802cea07782ab228Andy McFadden ALOGE("eglCreateWindowSurface error: %#x", eglGetError()); 56441e847feb0e055ecb004802802cea07782ab228Andy McFadden eglRelease(); 57441e847feb0e055ecb004802802cea07782ab228Andy McFadden return UNKNOWN_ERROR; 58441e847feb0e055ecb004802802cea07782ab228Andy McFadden } 59441e847feb0e055ecb004802802cea07782ab228Andy McFadden 60441e847feb0e055ecb004802802cea07782ab228Andy McFadden return NO_ERROR; 61441e847feb0e055ecb004802802cea07782ab228Andy McFadden} 62441e847feb0e055ecb004802802cea07782ab228Andy McFadden 63587c6fefcd3c1d05c608ff511cf3534bc765256eAndy McFaddenstatus_t EglWindow::createPbuffer(int width, int height) { 64587c6fefcd3c1d05c608ff511cf3534bc765256eAndy McFadden if (mEglSurface != EGL_NO_SURFACE) { 65587c6fefcd3c1d05c608ff511cf3534bc765256eAndy McFadden ALOGE("surface already created"); 66587c6fefcd3c1d05c608ff511cf3534bc765256eAndy McFadden return UNKNOWN_ERROR; 67587c6fefcd3c1d05c608ff511cf3534bc765256eAndy McFadden } 68587c6fefcd3c1d05c608ff511cf3534bc765256eAndy McFadden status_t err = eglSetupContext(true); 69587c6fefcd3c1d05c608ff511cf3534bc765256eAndy McFadden if (err != NO_ERROR) { 70587c6fefcd3c1d05c608ff511cf3534bc765256eAndy McFadden return err; 71587c6fefcd3c1d05c608ff511cf3534bc765256eAndy McFadden } 72587c6fefcd3c1d05c608ff511cf3534bc765256eAndy McFadden 73587c6fefcd3c1d05c608ff511cf3534bc765256eAndy McFadden mWidth = width; 74587c6fefcd3c1d05c608ff511cf3534bc765256eAndy McFadden mHeight = height; 75587c6fefcd3c1d05c608ff511cf3534bc765256eAndy McFadden 76587c6fefcd3c1d05c608ff511cf3534bc765256eAndy McFadden EGLint pbufferAttribs[] = { 77587c6fefcd3c1d05c608ff511cf3534bc765256eAndy McFadden EGL_WIDTH, width, 78587c6fefcd3c1d05c608ff511cf3534bc765256eAndy McFadden EGL_HEIGHT, height, 79587c6fefcd3c1d05c608ff511cf3534bc765256eAndy McFadden EGL_NONE 80587c6fefcd3c1d05c608ff511cf3534bc765256eAndy McFadden }; 81587c6fefcd3c1d05c608ff511cf3534bc765256eAndy McFadden mEglSurface = eglCreatePbufferSurface(mEglDisplay, mEglConfig, pbufferAttribs); 82587c6fefcd3c1d05c608ff511cf3534bc765256eAndy McFadden if (mEglSurface == EGL_NO_SURFACE) { 83587c6fefcd3c1d05c608ff511cf3534bc765256eAndy McFadden ALOGE("eglCreatePbufferSurface error: %#x", eglGetError()); 84587c6fefcd3c1d05c608ff511cf3534bc765256eAndy McFadden eglRelease(); 85587c6fefcd3c1d05c608ff511cf3534bc765256eAndy McFadden return UNKNOWN_ERROR; 86587c6fefcd3c1d05c608ff511cf3534bc765256eAndy McFadden } 87587c6fefcd3c1d05c608ff511cf3534bc765256eAndy McFadden 88587c6fefcd3c1d05c608ff511cf3534bc765256eAndy McFadden return NO_ERROR; 89587c6fefcd3c1d05c608ff511cf3534bc765256eAndy McFadden} 90587c6fefcd3c1d05c608ff511cf3534bc765256eAndy McFadden 91441e847feb0e055ecb004802802cea07782ab228Andy McFaddenstatus_t EglWindow::makeCurrent() const { 92441e847feb0e055ecb004802802cea07782ab228Andy McFadden if (!eglMakeCurrent(mEglDisplay, mEglSurface, mEglSurface, mEglContext)) { 93441e847feb0e055ecb004802802cea07782ab228Andy McFadden ALOGE("eglMakeCurrent failed: %#x", eglGetError()); 94441e847feb0e055ecb004802802cea07782ab228Andy McFadden return UNKNOWN_ERROR; 95441e847feb0e055ecb004802802cea07782ab228Andy McFadden } 96441e847feb0e055ecb004802802cea07782ab228Andy McFadden return NO_ERROR; 97441e847feb0e055ecb004802802cea07782ab228Andy McFadden} 98441e847feb0e055ecb004802802cea07782ab228Andy McFadden 99587c6fefcd3c1d05c608ff511cf3534bc765256eAndy McFaddenstatus_t EglWindow::eglSetupContext(bool forPbuffer) { 100441e847feb0e055ecb004802802cea07782ab228Andy McFadden EGLBoolean result; 101441e847feb0e055ecb004802802cea07782ab228Andy McFadden 102441e847feb0e055ecb004802802cea07782ab228Andy McFadden mEglDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY); 103441e847feb0e055ecb004802802cea07782ab228Andy McFadden if (mEglDisplay == EGL_NO_DISPLAY) { 104441e847feb0e055ecb004802802cea07782ab228Andy McFadden ALOGE("eglGetDisplay failed: %#x", eglGetError()); 105441e847feb0e055ecb004802802cea07782ab228Andy McFadden return UNKNOWN_ERROR; 106441e847feb0e055ecb004802802cea07782ab228Andy McFadden } 107441e847feb0e055ecb004802802cea07782ab228Andy McFadden 108441e847feb0e055ecb004802802cea07782ab228Andy McFadden EGLint majorVersion, minorVersion; 109441e847feb0e055ecb004802802cea07782ab228Andy McFadden result = eglInitialize(mEglDisplay, &majorVersion, &minorVersion); 110441e847feb0e055ecb004802802cea07782ab228Andy McFadden if (result != EGL_TRUE) { 111441e847feb0e055ecb004802802cea07782ab228Andy McFadden ALOGE("eglInitialize failed: %#x", eglGetError()); 112441e847feb0e055ecb004802802cea07782ab228Andy McFadden return UNKNOWN_ERROR; 113441e847feb0e055ecb004802802cea07782ab228Andy McFadden } 114441e847feb0e055ecb004802802cea07782ab228Andy McFadden ALOGV("Initialized EGL v%d.%d", majorVersion, minorVersion); 115441e847feb0e055ecb004802802cea07782ab228Andy McFadden 116441e847feb0e055ecb004802802cea07782ab228Andy McFadden EGLint numConfigs = 0; 117587c6fefcd3c1d05c608ff511cf3534bc765256eAndy McFadden EGLint windowConfigAttribs[] = { 118587c6fefcd3c1d05c608ff511cf3534bc765256eAndy McFadden EGL_SURFACE_TYPE, EGL_WINDOW_BIT, 119587c6fefcd3c1d05c608ff511cf3534bc765256eAndy McFadden EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT, 120587c6fefcd3c1d05c608ff511cf3534bc765256eAndy McFadden EGL_RECORDABLE_ANDROID, 1, 121587c6fefcd3c1d05c608ff511cf3534bc765256eAndy McFadden EGL_RED_SIZE, 8, 122587c6fefcd3c1d05c608ff511cf3534bc765256eAndy McFadden EGL_GREEN_SIZE, 8, 123587c6fefcd3c1d05c608ff511cf3534bc765256eAndy McFadden EGL_BLUE_SIZE, 8, 124587c6fefcd3c1d05c608ff511cf3534bc765256eAndy McFadden // no alpha 125587c6fefcd3c1d05c608ff511cf3534bc765256eAndy McFadden EGL_NONE 126587c6fefcd3c1d05c608ff511cf3534bc765256eAndy McFadden }; 127587c6fefcd3c1d05c608ff511cf3534bc765256eAndy McFadden EGLint pbufferConfigAttribs[] = { 128587c6fefcd3c1d05c608ff511cf3534bc765256eAndy McFadden EGL_SURFACE_TYPE, EGL_PBUFFER_BIT, 129587c6fefcd3c1d05c608ff511cf3534bc765256eAndy McFadden EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT, 130587c6fefcd3c1d05c608ff511cf3534bc765256eAndy McFadden EGL_RED_SIZE, 8, 131587c6fefcd3c1d05c608ff511cf3534bc765256eAndy McFadden EGL_GREEN_SIZE, 8, 132587c6fefcd3c1d05c608ff511cf3534bc765256eAndy McFadden EGL_BLUE_SIZE, 8, 133587c6fefcd3c1d05c608ff511cf3534bc765256eAndy McFadden EGL_ALPHA_SIZE, 8, 134587c6fefcd3c1d05c608ff511cf3534bc765256eAndy McFadden EGL_NONE 135441e847feb0e055ecb004802802cea07782ab228Andy McFadden }; 136587c6fefcd3c1d05c608ff511cf3534bc765256eAndy McFadden result = eglChooseConfig(mEglDisplay, 137587c6fefcd3c1d05c608ff511cf3534bc765256eAndy McFadden forPbuffer ? pbufferConfigAttribs : windowConfigAttribs, 138587c6fefcd3c1d05c608ff511cf3534bc765256eAndy McFadden &mEglConfig, 1, &numConfigs); 139441e847feb0e055ecb004802802cea07782ab228Andy McFadden if (result != EGL_TRUE) { 140441e847feb0e055ecb004802802cea07782ab228Andy McFadden ALOGE("eglChooseConfig error: %#x", eglGetError()); 141441e847feb0e055ecb004802802cea07782ab228Andy McFadden return UNKNOWN_ERROR; 142441e847feb0e055ecb004802802cea07782ab228Andy McFadden } 143441e847feb0e055ecb004802802cea07782ab228Andy McFadden 144441e847feb0e055ecb004802802cea07782ab228Andy McFadden EGLint contextAttribs[] = { 145441e847feb0e055ecb004802802cea07782ab228Andy McFadden EGL_CONTEXT_CLIENT_VERSION, 2, 146441e847feb0e055ecb004802802cea07782ab228Andy McFadden EGL_NONE 147441e847feb0e055ecb004802802cea07782ab228Andy McFadden }; 148441e847feb0e055ecb004802802cea07782ab228Andy McFadden mEglContext = eglCreateContext(mEglDisplay, mEglConfig, EGL_NO_CONTEXT, 149441e847feb0e055ecb004802802cea07782ab228Andy McFadden contextAttribs); 150441e847feb0e055ecb004802802cea07782ab228Andy McFadden if (mEglContext == EGL_NO_CONTEXT) { 151441e847feb0e055ecb004802802cea07782ab228Andy McFadden ALOGE("eglCreateContext error: %#x", eglGetError()); 152441e847feb0e055ecb004802802cea07782ab228Andy McFadden return UNKNOWN_ERROR; 153441e847feb0e055ecb004802802cea07782ab228Andy McFadden } 154441e847feb0e055ecb004802802cea07782ab228Andy McFadden 155441e847feb0e055ecb004802802cea07782ab228Andy McFadden return NO_ERROR; 156441e847feb0e055ecb004802802cea07782ab228Andy McFadden} 157441e847feb0e055ecb004802802cea07782ab228Andy McFadden 158441e847feb0e055ecb004802802cea07782ab228Andy McFaddenvoid EglWindow::eglRelease() { 159441e847feb0e055ecb004802802cea07782ab228Andy McFadden ALOGV("EglWindow::eglRelease"); 160441e847feb0e055ecb004802802cea07782ab228Andy McFadden if (mEglDisplay != EGL_NO_DISPLAY) { 161441e847feb0e055ecb004802802cea07782ab228Andy McFadden eglMakeCurrent(mEglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, 162441e847feb0e055ecb004802802cea07782ab228Andy McFadden EGL_NO_CONTEXT); 163441e847feb0e055ecb004802802cea07782ab228Andy McFadden 164441e847feb0e055ecb004802802cea07782ab228Andy McFadden if (mEglContext != EGL_NO_CONTEXT) { 165441e847feb0e055ecb004802802cea07782ab228Andy McFadden eglDestroyContext(mEglDisplay, mEglContext); 166441e847feb0e055ecb004802802cea07782ab228Andy McFadden } 167441e847feb0e055ecb004802802cea07782ab228Andy McFadden 168441e847feb0e055ecb004802802cea07782ab228Andy McFadden if (mEglSurface != EGL_NO_SURFACE) { 169441e847feb0e055ecb004802802cea07782ab228Andy McFadden eglDestroySurface(mEglDisplay, mEglSurface); 170441e847feb0e055ecb004802802cea07782ab228Andy McFadden } 171441e847feb0e055ecb004802802cea07782ab228Andy McFadden } 172441e847feb0e055ecb004802802cea07782ab228Andy McFadden 173441e847feb0e055ecb004802802cea07782ab228Andy McFadden mEglDisplay = EGL_NO_DISPLAY; 174441e847feb0e055ecb004802802cea07782ab228Andy McFadden mEglContext = EGL_NO_CONTEXT; 175441e847feb0e055ecb004802802cea07782ab228Andy McFadden mEglSurface = EGL_NO_SURFACE; 176441e847feb0e055ecb004802802cea07782ab228Andy McFadden mEglConfig = NULL; 177441e847feb0e055ecb004802802cea07782ab228Andy McFadden 178441e847feb0e055ecb004802802cea07782ab228Andy McFadden eglReleaseThread(); 179441e847feb0e055ecb004802802cea07782ab228Andy McFadden} 180441e847feb0e055ecb004802802cea07782ab228Andy McFadden 181441e847feb0e055ecb004802802cea07782ab228Andy McFadden// Sets the presentation time on the current EGL buffer. 182441e847feb0e055ecb004802802cea07782ab228Andy McFaddenvoid EglWindow::presentationTime(nsecs_t whenNsec) const { 183441e847feb0e055ecb004802802cea07782ab228Andy McFadden eglPresentationTimeANDROID(mEglDisplay, mEglSurface, whenNsec); 184441e847feb0e055ecb004802802cea07782ab228Andy McFadden} 185441e847feb0e055ecb004802802cea07782ab228Andy McFadden 186441e847feb0e055ecb004802802cea07782ab228Andy McFadden// Swaps the EGL buffer. 187441e847feb0e055ecb004802802cea07782ab228Andy McFaddenvoid EglWindow::swapBuffers() const { 188441e847feb0e055ecb004802802cea07782ab228Andy McFadden eglSwapBuffers(mEglDisplay, mEglSurface); 189441e847feb0e055ecb004802802cea07782ab228Andy McFadden} 190