Add support for EGLImage to GrGLInterface
BUG=skia: Review URL: https://codereview.chromium.org/1434813002
This commit is contained in:
parent
0dfa62c977
commit
b1a32ad517
@ -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; }
|
||||
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user