Add support for EGLImage to GrGLInterface

BUG=skia:

Review URL: https://codereview.chromium.org/1434813002
This commit is contained in:
bsalomon 2015-11-16 06:48:44 -08:00 committed by Commit bot
parent 0dfa62c977
commit b1a32ad517
12 changed files with 113 additions and 27 deletions

View File

@ -17,7 +17,8 @@ struct GrGLInterface;
/**
* This helper queries the current GL context for its extensions, remembers them, and can be
* queried. It supports both glGetString- and glGetStringi-style extension string APIs and will
* use the latter if it is available.
* use the latter if it is available. It also will query for EGL extensions if a eglQueryString
* implementation is provided.
*/
class SK_API GrGLExtensions {
public:
@ -40,7 +41,9 @@ public:
bool init(GrGLStandard standard,
GrGLGetStringProc getString,
GrGLGetStringiProc getStringi,
GrGLGetIntegervProc getIntegerv);
GrGLGetIntegervProc getIntegerv,
GrEGLQueryStringProc queryString,
GrEGLDisplay eglDisplay);
bool isInitialized() const { return fInitialized; }

View File

@ -349,6 +349,11 @@ typedef GrGLvoid (GR_GL_FUNCTION_TYPE* GrGLPushDebugGroupProc)(GrGLenum source,
typedef GrGLvoid (GR_GL_FUNCTION_TYPE* GrGLPopDebugGroupProc)();
typedef GrGLvoid (GR_GL_FUNCTION_TYPE* GrGLObjectLabelProc)(GrGLenum identifier, GrGLuint name, GrGLsizei length, const GrGLchar *label);
/** EGL functions */
typedef const char* (GR_GL_FUNCTION_TYPE* GrEGLQueryStringProc)(GrEGLDisplay dpy, GrEGLint name);
typedef GrEGLDisplay (GR_GL_FUNCTION_TYPE* GrEGLGetCurrentDisplayProc)();
typedef GrEGLImageKHR (GR_GL_FUNCTION_TYPE* GrEGLCreateImageProc)(GrEGLDisplay dpy, GrEGLContext ctx, GrEGLenum target, GrEGLClientBuffer buffer, const GrEGLint *attrib_list);
typedef GrEGLBoolean (GR_GL_FUNCTION_TYPE* GrEGLDestroyImageProc)(GrEGLDisplay dpy, GrEGLImageKHR image);
} // extern "C"
#endif

View File

@ -128,8 +128,6 @@ private:
typedef SkRefCnt INHERITED;
public:
GrGLInterface();
static GrGLInterface* NewClone(const GrGLInterface*);
@ -498,6 +496,10 @@ public:
GLPtr<GrGLPushDebugGroupProc> fPushDebugGroup;
GLPtr<GrGLPopDebugGroupProc> fPopDebugGroup;
GLPtr<GrGLObjectLabelProc> fObjectLabel;
/* EGL functions */
GLPtr<GrEGLCreateImageProc> fCreateImage;
GLPtr<GrEGLDestroyImageProc> fDestroyImage;
} fFunctions;
// Per-GL func callback

View File

@ -58,6 +58,18 @@ typedef signed long int GrGLintptr;
typedef signed long int GrGLsizeiptr;
#endif
/**
* EGL types.
*/
typedef void* GrEGLImageKHR;
typedef void* GrEGLDisplay;
typedef void* GrEGLContext;
typedef void* GrEGLClientBuffer;
typedef unsigned int GrEGLenum;
typedef int32_t GrEGLint;
typedef unsigned int GrEGLBoolean;
///////////////////////////////////////////////////////////////////////////////
/**
* Types for interacting with GL resources created externally to Skia. GrBackendObjects for GL

View File

@ -14,6 +14,8 @@
#define GET_PROC_SUFFIX(F, S) functions->f ## F = (GrGL ## F ## Proc) get(ctx, "gl" #F #S)
#define GET_PROC_LOCAL(F) GrGL ## F ## Proc F = (GrGL ## F ## Proc) get(ctx, "gl" #F)
#define GET_EGL_PROC_SUFFIX(F, S) functions->f ## F = (GrEGL ## F ## Proc) get(ctx, "egl" #F #S)
const GrGLInterface* GrGLAssembleInterface(void* ctx, GrGLGetProc get) {
GET_PROC_LOCAL(GetString);
if (nullptr == GetString) {
@ -35,6 +37,21 @@ const GrGLInterface* GrGLAssembleInterface(void* ctx, GrGLGetProc get) {
return nullptr;
}
static void get_egl_query_and_display(GrEGLQueryStringProc* queryString, GrEGLDisplay* display,
void* ctx, GrGLGetProc get) {
*queryString = (GrEGLQueryStringProc) get(ctx, "eglQueryString");
*display = GR_EGL_NO_DISPLAY;
if (*queryString) {
GrEGLGetCurrentDisplayProc getCurrentDisplay =
(GrEGLGetCurrentDisplayProc) get(ctx, "eglGetCurrentDisplay");
if (getCurrentDisplay) {
*display = getCurrentDisplay();
} else {
*queryString = nullptr;
}
}
}
const GrGLInterface* GrGLAssembleGLInterface(void* ctx, GrGLGetProc get) {
GET_PROC_LOCAL(GetString);
GET_PROC_LOCAL(GetStringi);
@ -53,8 +70,12 @@ const GrGLInterface* GrGLAssembleGLInterface(void* ctx, GrGLGetProc get) {
return nullptr;
}
GrEGLQueryStringProc queryString;
GrEGLDisplay display;
get_egl_query_and_display(&queryString, &display, ctx, get);
GrGLExtensions extensions;
if (!extensions.init(kGL_GrGLStandard, GetString, GetStringi, GetIntegerv)) {
if (!extensions.init(kGL_GrGLStandard, GetString, GetStringi, GetIntegerv, queryString,
display)) {
return nullptr;
}
@ -462,6 +483,11 @@ const GrGLInterface* GrGLAssembleGLInterface(void* ctx, GrGLGetProc get) {
GET_PROC(ObjectLabel);
}
if (extensions.has("EGL_KHR_image") || extensions.has("EGL_KHR_image_base")) {
GET_EGL_PROC_SUFFIX(CreateImage, KHR);
GET_EGL_PROC_SUFFIX(DestroyImage, KHR);
}
interface->fStandard = kGL_GrGLStandard;
interface->fExtensions.swap(&extensions);
@ -483,8 +509,12 @@ const GrGLInterface* GrGLAssembleGLESInterface(void* ctx, GrGLGetProc get) {
GET_PROC_LOCAL(GetIntegerv);
GET_PROC_LOCAL(GetStringi);
GrEGLQueryStringProc queryString;
GrEGLDisplay display;
get_egl_query_and_display(&queryString, &display, ctx, get);
GrGLExtensions extensions;
if (!extensions.init(kGLES_GrGLStandard, GetString, GetStringi, GetIntegerv)) {
if (!extensions.init(kGLES_GrGLStandard, GetString, GetStringi, GetIntegerv, queryString,
display)) {
return nullptr;
}
@ -766,6 +796,11 @@ const GrGLInterface* GrGLAssembleGLESInterface(void* ctx, GrGLGetProc get) {
GET_PROC_SUFFIX(BindUniformLocation, CHROMIUM);
}
if (extensions.has("EGL_KHR_image") || extensions.has("EGL_KHR_image_base")) {
GET_EGL_PROC_SUFFIX(CreateImage, KHR);
GET_EGL_PROC_SUFFIX(DestroyImage, KHR);
}
interface->fStandard = kGLES_GrGLStandard;
interface->fExtensions.swap(&extensions);

View File

@ -488,6 +488,6 @@ const GrGLInterface* GrGLCreateNullInterface() {
functions->fBindFragDataLocationIndexed = noOpGLBindFragDataLocationIndexed;
interface->fExtensions.init(kGL_GrGLStandard, functions->fGetString, functions->fGetStringi,
functions->fGetIntegerv);
functions->fGetIntegerv, nullptr, GR_EGL_NO_DISPLAY);
return interface;
}

View File

@ -928,4 +928,8 @@
#define GR_GL_PROGRAM_PIPELINE 0x82E4
#define GR_GL_SAMPLER 0x82E6
/* EGL Defines */
#define GR_EGL_NO_DISPLAY ((GrEGLDisplay)0)
#define GR_EGL_EXTENSIONS 0x3055
#endif

View File

@ -41,14 +41,36 @@ GrGLExtensions& GrGLExtensions::operator=(const GrGLExtensions& that) {
return *this;
}
static void eat_space_sep_strings(SkTArray<SkString>* out, const char in[]) {
if (!in) {
return;
}
while (true) {
// skip over multiple spaces between extensions
while (' ' == *in) {
++in;
}
// quit once we reach the end of the string.
if ('\0' == *in) {
break;
}
// we found an extension
size_t length = strcspn(in, " ");
out->push_back().set(in, length);
in += length;
}
}
bool GrGLExtensions::init(GrGLStandard standard,
GrGLGetStringProc getString,
GrGLGetStringiProc getStringi,
GrGLGetIntegervProc getIntegerv) {
GrGLGetIntegervProc getIntegerv,
GrEGLQueryStringProc queryString,
GrEGLDisplay eglDisplay) {
fInitialized = false;
fStrings->reset();
if (nullptr == getString) {
if (!getString) {
return false;
}
@ -62,7 +84,7 @@ bool GrGLExtensions::init(GrGLStandard standard,
bool indexed = version >= GR_GL_VER(3, 0);
if (indexed) {
if (nullptr == getStringi || nullptr == getIntegerv) {
if (!getStringi || !getIntegerv) {
return false;
}
GrGLint extensionCnt = 0;
@ -74,23 +96,15 @@ bool GrGLExtensions::init(GrGLStandard standard,
}
} else {
const char* extensions = (const char*) getString(GR_GL_EXTENSIONS);
if (nullptr == extensions) {
if (!extensions) {
return false;
}
while (true) {
// skip over multiple spaces between extensions
while (' ' == *extensions) {
++extensions;
}
// quit once we reach the end of the string.
if ('\0' == *extensions) {
break;
}
// we found an extension
size_t length = strcspn(extensions, " ");
fStrings->push_back().set(extensions, length);
extensions += length;
}
eat_space_sep_strings(fStrings, extensions);
}
if (queryString) {
const char* extensions = queryString(eglDisplay, GR_EGL_EXTENSIONS);
eat_space_sep_strings(fStrings, extensions);
}
if (!fStrings->empty()) {
SkTLessFunctionToFunctorAdaptor<SkString, extension_compare> cmp;

View File

@ -726,5 +726,12 @@ bool GrGLInterface::validate() const {
}
}
if (fExtensions.has("EGL_KHR_image") || fExtensions.has("EGL_KHR_image_base")) {
if (nullptr == fFunctions.fCreateImage ||
nullptr == fFunctions.fDestroyImage) {
RETURN_FALSE_INTERFACE
}
}
return true;
}

View File

@ -491,7 +491,7 @@ static GrGLInterface* create_null_interface(State* state) {
functions->fBindFragDataLocationIndexed = noOpGLBindFragDataLocationIndexed;
interface->fExtensions.init(kGL_GrGLStandard, functions->fGetString, functions->fGetStringi,
functions->fGetIntegerv);
functions->fGetIntegerv, nullptr, GR_EGL_NO_DISPLAY);
return interface;
}

View File

@ -223,6 +223,10 @@ static GrGLFuncPtr android_get_gl_proc(void* ctx, const char name[]) {
return (GrGLFuncPtr) glGetRenderbufferParameteriv;
} else if (0 == strcmp("glRenderbufferStorage", name)) {
return (GrGLFuncPtr) glRenderbufferStorage;
} else if (0 == strcmp("eglQueryString", name)) {
return (GrGLFuncPtr) eglQueryString;
} else if (0 == strcmp("eglGetCurrentDisplay", name)) {
return (GrGLFuncPtr) eglGetCurrentDisplay;
}
return eglGetProcAddress(name);
}

View File

@ -983,7 +983,7 @@ const GrGLInterface* GrGLCreateDebugInterface() {
noOpGLBindFragDataLocationIndexed;
interface->fExtensions.init(kGL_GrGLStandard, functions->fGetString, functions->fGetStringi,
functions->fGetIntegerv);
functions->fGetIntegerv, nullptr, GR_EGL_NO_DISPLAY);
return interface;
}