gpu_tonemapper: Use individual EGL contexts.

- Use individual EGL contexts for each tone-mapping
  session.
- Having one context make multiple sessions serial, this
  helps in making this parallel when possible.
- Resolves error messages which happened when the context
  was deleted during mirroring.

Change-Id: Ia8738551b4189dccffb233320a9d69fcfd7f0118
Crs-fixed: 1115057
This commit is contained in:
Arun Kumar K.R
2017-01-23 17:16:55 -08:00
parent d612a57d8f
commit 1b04a4ee50
5 changed files with 57 additions and 51 deletions

View File

@@ -27,9 +27,6 @@ Tonemapper *TonemapperFactory_GetInstance(int type, void *colorMap, int colorMap
void *lutXform, int lutXformSize) void *lutXform, int lutXformSize)
//---------------------------------------------------------------------------------------------------------------------------------------------------------- //----------------------------------------------------------------------------------------------------------------------------------------------------------
{ {
// initializes the engine - does nothing if already initialized
engine_initialize();
// build the tonemapper // build the tonemapper
Tonemapper *tonemapper = Tonemapper::build(type, colorMap, colorMapSize, lutXform, lutXformSize); Tonemapper *tonemapper = Tonemapper::build(type, colorMap, colorMapSize, lutXform, lutXformSize);
@@ -40,6 +37,4 @@ Tonemapper *TonemapperFactory_GetInstance(int type, void *colorMap, int colorMap
void TonemapperFactory_Destroy() void TonemapperFactory_Destroy()
//------------------------------------------ //------------------------------------------
{ {
// shutdown the engine
engine_shutdown();
} }

View File

@@ -39,7 +39,7 @@ Tonemapper::Tonemapper()
Tonemapper::~Tonemapper() Tonemapper::~Tonemapper()
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
{ {
engine_bind(); engine_bind(engineContext);
engine_deleteInputBuffer(tonemapTexture); engine_deleteInputBuffer(tonemapTexture);
engine_deleteInputBuffer(lutXformTexture); engine_deleteInputBuffer(lutXformTexture);
engine_deleteProgram(programID); engine_deleteProgram(programID);
@@ -50,6 +50,8 @@ Tonemapper::~Tonemapper()
delete eglImageWrapper; delete eglImageWrapper;
eglImageWrapper = 0; eglImageWrapper = 0;
} }
engine_shutdown(engineContext);
} }
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
@@ -61,10 +63,14 @@ Tonemapper *Tonemapper::build(int type, void *colorMap, int colorMapSize, void *
ALOGE("Invalid Color Map size = %d", colorMapSize); ALOGE("Invalid Color Map size = %d", colorMapSize);
return NULL; return NULL;
} }
engine_bind();
// build new tonemapper // build new tonemapper
Tonemapper *tonemapper = new Tonemapper(); Tonemapper *tonemapper = new Tonemapper();
tonemapper->engineContext = engine_initialize();
engine_bind(tonemapper->engineContext);
// load the 3d lut // load the 3d lut
tonemapper->tonemapTexture = engine_load3DTexture(colorMap, colorMapSize, 0); tonemapper->tonemapTexture = engine_load3DTexture(colorMap, colorMapSize, 0);
// load the non-uniform xform // load the non-uniform xform
@@ -101,7 +107,7 @@ int Tonemapper::blit(const void *dst, const void *src, int srcFenceFd)
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
{ {
// make current // make current
engine_bind(); engine_bind(engineContext);
// create eglimages if required // create eglimages if required
EGLImageBuffer *dst_buffer = eglImageWrapper->wrap(dst); EGLImageBuffer *dst_buffer = eglImageWrapper->wrap(dst);

View File

@@ -24,9 +24,11 @@
#define TONEMAP_INVERSE 1 #define TONEMAP_INVERSE 1
#include "EGLImageWrapper.h" #include "EGLImageWrapper.h"
#include "engine.h"
class Tonemapper { class Tonemapper {
private: private:
void* engineContext;
unsigned int tonemapTexture; unsigned int tonemapTexture;
unsigned int lutXformTexture; unsigned int lutXformTexture;
unsigned int programID; unsigned int programID;

View File

@@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2016, The Linux Foundation. All rights reserved. * Copyright (c) 2016-2017, The Linux Foundation. All rights reserved.
* Not a Contribution. * Not a Contribution.
* *
* Copyright 2015 The Android Open Source Project * Copyright 2015 The Android Open Source Project
@@ -20,9 +20,9 @@
#ifndef __TONEMAPPER_ENGINE_H__ #ifndef __TONEMAPPER_ENGINE_H__
#define __TONEMAPPER_ENGINE_H__ #define __TONEMAPPER_ENGINE_H__
bool engine_initialize(); void* engine_initialize();
void engine_bind(); void engine_bind(void*);
void engine_shutdown(); void engine_shutdown(void*);
unsigned int engine_loadProgram(int, const char **, int, const char **); unsigned int engine_loadProgram(int, const char **, int, const char **);
void engine_setProgram(int); void engine_setProgram(int);

View File

@@ -1,5 +1,5 @@
/* /*
* Copyright (c) 2016, The Linux Foundation. All rights reserved. * Copyright (c) 2016-2017, The Linux Foundation. All rights reserved.
* Not a Contribution. * Not a Contribution.
* *
* Copyright 2015 The Android Open Source Project * Copyright 2015 The Android Open Source Project
@@ -24,37 +24,42 @@
void checkGlError(const char *, int); void checkGlError(const char *, int);
void checkEglError(const char *, int); void checkEglError(const char *, int);
static EGLDisplay eglDisplay; class EngineContext {
static EGLContext eglContext; public:
static EGLSurface eglSurface; EGLDisplay eglDisplay;
EGLContext eglContext;
static bool isEngineInitialized = false; EGLSurface eglSurface;
EngineContext()
{
eglDisplay = EGL_NO_DISPLAY;
eglContext = EGL_NO_CONTEXT;
eglSurface = EGL_NO_SURFACE;
}
};
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// Make Current // Make Current
void engine_bind() void engine_bind(void* context)
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
{ {
EGL(eglMakeCurrent(eglDisplay, eglSurface, eglSurface, eglContext)); EngineContext* engineContext = (EngineContext*)(context);
EGL(eglMakeCurrent(engineContext->eglDisplay, engineContext->eglSurface, engineContext->eglSurface, engineContext->eglContext));
} }
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// initialize GL // initialize GL
// //
bool engine_initialize() void* engine_initialize()
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
{ {
if (isEngineInitialized) EngineContext* engineContext = new EngineContext();
return true;
EGLBoolean result = false;
// display // display
eglDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY); engineContext->eglDisplay = eglGetDisplay(EGL_DEFAULT_DISPLAY);
EGL(eglBindAPI(EGL_OPENGL_ES_API)); EGL(eglBindAPI(EGL_OPENGL_ES_API));
// initialize // initialize
EGL(eglInitialize(eglDisplay, 0, 0)); EGL(eglInitialize(engineContext->eglDisplay, 0, 0));
// config // config
EGLConfig eglConfig; EGLConfig eglConfig;
@@ -65,38 +70,36 @@ bool engine_initialize()
EGL_ALPHA_SIZE, 8, EGL_ALPHA_SIZE, 8,
EGL_NONE}; EGL_NONE};
int numConfig = 0; int numConfig = 0;
EGL(eglChooseConfig(eglDisplay, eglConfigAttribList, &eglConfig, 1, &numConfig)); EGL(eglChooseConfig(engineContext->eglDisplay, eglConfigAttribList, &eglConfig, 1, &numConfig));
// context // context
EGLint eglContextAttribList[] = {EGL_CONTEXT_CLIENT_VERSION, 3, EGL_NONE}; EGLint eglContextAttribList[] = {EGL_CONTEXT_CLIENT_VERSION, 3, EGL_NONE};
eglContext = eglCreateContext(eglDisplay, eglConfig, NULL, eglContextAttribList); engineContext->eglContext = eglCreateContext(engineContext->eglDisplay, eglConfig, NULL, eglContextAttribList);
// surface // surface
EGLint eglSurfaceAttribList[] = {EGL_WIDTH, 1, EGL_HEIGHT, 1, EGL_NONE, EGL_NONE}; EGLint eglSurfaceAttribList[] = {EGL_WIDTH, 1, EGL_HEIGHT, 1, EGL_NONE, EGL_NONE};
eglSurface = eglCreatePbufferSurface(eglDisplay, eglConfig, eglSurfaceAttribList); engineContext->eglSurface = eglCreatePbufferSurface(engineContext->eglDisplay, eglConfig, eglSurfaceAttribList);
result = (EGL_TRUE == eglMakeCurrent(eglDisplay, eglSurface, eglSurface, eglContext)); eglMakeCurrent(engineContext->eglDisplay, engineContext->eglSurface, engineContext->eglSurface, engineContext->eglContext);
isEngineInitialized = result; ALOGI("In %s context = %p", __FUNCTION__, (void *)(engineContext->eglContext));
ALOGI("In %s result = %d context = %p", __FUNCTION__, result, (void *)eglContext); return (void*)(engineContext);
return result;
} }
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
// Shutdown. // Shutdown.
void engine_shutdown() void engine_shutdown(void* context)
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
{ {
EGL(eglMakeCurrent(eglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT)); EngineContext* engineContext = (EngineContext*)context;
EGL(eglDestroySurface(eglDisplay, eglSurface)); EGL(eglMakeCurrent(engineContext->eglDisplay, EGL_NO_SURFACE, EGL_NO_SURFACE, EGL_NO_CONTEXT));
EGL(eglDestroyContext(eglDisplay, eglContext)); EGL(eglDestroySurface(engineContext->eglDisplay, engineContext->eglSurface));
EGL(eglTerminate(eglDisplay)); EGL(eglDestroyContext(engineContext->eglDisplay, engineContext->eglContext));
eglDisplay = EGL_NO_DISPLAY; EGL(eglTerminate(engineContext->eglDisplay));
eglContext = EGL_NO_CONTEXT; engineContext->eglDisplay = EGL_NO_DISPLAY;
eglSurface = EGL_NO_SURFACE; engineContext->eglContext = EGL_NO_CONTEXT;
isEngineInitialized = false; engineContext->eglSurface = EGL_NO_SURFACE;
} }
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
@@ -206,14 +209,14 @@ void WaitOnNativeFence(int fd)
if (fd != -1) { if (fd != -1) {
EGLint attribs[] = {EGL_SYNC_NATIVE_FENCE_FD_ANDROID, fd, EGL_NONE}; EGLint attribs[] = {EGL_SYNC_NATIVE_FENCE_FD_ANDROID, fd, EGL_NONE};
EGLSyncKHR sync = eglCreateSyncKHR(eglDisplay, EGL_SYNC_NATIVE_FENCE_ANDROID, attribs); EGLSyncKHR sync = eglCreateSyncKHR(eglGetCurrentDisplay(), EGL_SYNC_NATIVE_FENCE_ANDROID, attribs);
if (sync == EGL_NO_SYNC_KHR) { if (sync == EGL_NO_SYNC_KHR) {
ALOGE("%s - Failed to Create sync from source fd", __FUNCTION__); ALOGE("%s - Failed to Create sync from source fd", __FUNCTION__);
} else { } else {
// the gpu will wait for this sync - not this cpu thread. // the gpu will wait for this sync - not this cpu thread.
EGL(eglWaitSyncKHR(eglDisplay, sync, 0)); EGL(eglWaitSyncKHR(eglGetCurrentDisplay(), sync, 0));
EGL(eglDestroySyncKHR(eglDisplay, sync)); EGL(eglDestroySyncKHR(eglGetCurrentDisplay(), sync));
} }
} }
} }
@@ -224,16 +227,16 @@ int CreateNativeFence()
{ {
int fd = -1; int fd = -1;
EGLSyncKHR sync = eglCreateSyncKHR(eglDisplay, EGL_SYNC_NATIVE_FENCE_ANDROID, NULL); EGLSyncKHR sync = eglCreateSyncKHR(eglGetCurrentDisplay(), EGL_SYNC_NATIVE_FENCE_ANDROID, NULL);
GL(glFlush()); GL(glFlush());
if (sync == EGL_NO_SYNC_KHR) { if (sync == EGL_NO_SYNC_KHR) {
ALOGE("%s - Failed to Create Native Fence sync", __FUNCTION__); ALOGE("%s - Failed to Create Native Fence sync", __FUNCTION__);
} else { } else {
fd = eglDupNativeFenceFDANDROID(eglDisplay, sync); fd = eglDupNativeFenceFDANDROID(eglGetCurrentDisplay(), sync);
if (fd == EGL_NO_NATIVE_FENCE_FD_ANDROID) { if (fd == EGL_NO_NATIVE_FENCE_FD_ANDROID) {
ALOGE("%s - Failed to dup sync", __FUNCTION__); ALOGE("%s - Failed to dup sync", __FUNCTION__);
} }
EGL(eglDestroySyncKHR(eglDisplay, sync)); EGL(eglDestroySyncKHR(eglGetCurrentDisplay(), sync));
} }
return fd; return fd;