diff --git a/CMakeLists.txt b/CMakeLists.txt index a03fac31..f7dee06e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -44,6 +44,8 @@ option (ENABLE_TESTS "Enable additional tests" OFF) option (ENABLE_MULTIARCH "Enable multiarch support." ON) +option (ENABLE_VIVANTE "Enable Vivante support." OFF) + if (ANDROID) message (FATAL_ERROR "Android is no longer supported (https://git.io/vH2gW)") endif () @@ -205,6 +207,14 @@ if (ENABLE_EGL AND NOT ENABLE_X11) add_definitions (-DEGL_NO_X11) endif () +if (ENABLE_VIVANTE) + find_package (Vivante) + if (Vivante_FOUND) + add_definitions (-DHAVE_VIVANTE_G2D) + else() + message (FATAL_ERROR "Vivante requested but not found.") + endif() +endif () ############################################################################## # Set global build options diff --git a/cmake/FindVivante.cmake b/cmake/FindVivante.cmake new file mode 100644 index 00000000..6ec13525 --- /dev/null +++ b/cmake/FindVivante.cmake @@ -0,0 +1,29 @@ +# - Vivante headers and libraries +#set (Vivante_INC_SEARCH_PATH "usr/include") +find_path (Vivante_G2D_INCLUDE_DIR g2d.h + PATHS ${Vivante_INC_SEARCH_PATH} + DOC "The directory where gd2.h resides" + ) + +find_library (Vivante_G2D_LIBRARY libg2d.so + PATHS ${Vivante_LIB_SEARCH_PATH} + DOC "The directory where libg2d resides" + ) +find_library (Vivante_VDK_LIBRARY libVDK.so + PATHS ${Vivante_LIB_SEARCH_PATH} + DOC "The directory where libVDK resides" + ) + +if (Vivante_G2D_INCLUDE_DIR AND Vivante_G2D_LIBRARY AND Vivante_VDK_LIBRARY) + set (Vivante_FOUND 1) +endif () + +mark_as_advanced ( + Vivante_G2D_INCLUDE_DIR + Vivante_G2D_LIBRARY + Vivante_VDK_LIBRARY +) + +mark_as_advanced ( + Vivante_FOUND +) diff --git a/retrace/CMakeLists.txt b/retrace/CMakeLists.txt index 10ae7915..2a7fea81 100644 --- a/retrace/CMakeLists.txt +++ b/retrace/CMakeLists.txt @@ -150,6 +150,7 @@ if (WIN32 OR APPLE OR X11_FOUND) # http://stackoverflow.com/questions/2702628/gdb-cannot-find-new-threads-generic-error ${CMAKE_THREAD_LIBS_INIT} ${CMAKE_DL_LIBS} + ${Vivante_G2D_LIBRARY} ) endif () @@ -173,6 +174,8 @@ if (ENABLE_EGL AND ENABLE_X11 AND X11_FOUND AND NOT WIN32 AND NOT APPLE AND NOT ${X11_X11_LIB} ${CMAKE_THREAD_LIBS_INIT} ${CMAKE_DL_LIBS} + ${Vivante_G2D_LIBRARY} + ${Vivante_VDK_LIBRARY} ) install (TARGETS eglretrace RUNTIME DESTINATION bin) endif () diff --git a/retrace/glretrace.py b/retrace/glretrace.py index 7ac7e2c8..2d2e2fbf 100644 --- a/retrace/glretrace.py +++ b/retrace/glretrace.py @@ -240,6 +240,59 @@ def invokeFunction(self, function): print(' glretrace::trackResourceName(program, programInterface, index, traced_name);') if function.name == "glGetProgramResourceiv": print(' glretrace::mapResourceLocation(program, programInterface, index, call.arg(4).toArray(), call.arg(7).toArray(), _location_map);') + if function.name == "glTexDirectVIVMap" or function.name == "glTexDirectMapVIV" or function.name == "glTexDirectTiledMapVIV": + print('#if defined(HAVE_VIVANTE_G2D)') + print(' GLint tex;') + print(' glGetIntegerv(GL_TEXTURE_BINDING_2D, &tex);') + print(' int32_t size = 0;') + print(' switch(format){') + print(' case GL_VIV_YV12:') + print(' case GL_VIV_I420:') + print(' case GL_VIV_NV12:') + print(' case GL_VIV_NV21:') + print(' size=width * height * 3 / 2;') + print(' break;') + print(' case GL_RGBA:') + print(' case GL_BGRA_EXT:') + print(' size=width * height * 4;') + print(' break;') + print(' case GL_RGB:') + print(' size=width * height *3;') + print(' break;') + print(' case GL_VIV_YUY2:') + print(' case GL_VIV_UYVY:') + print(' case GL_RGB565_OES:') + print(' size=width * height *2;') + print(' break;') + print(' default:') + print(' break;') + print(' }') + print(' if(tex != 0)') + print(' {') + print(' TEXDIRECTVIVDATA &data = _directTextureDataMap[tex];') + print(' if(data.privateData == 0) // new entry') + print(' {') + print(' data.privateData = alloc_dma_buffer(size, &data.logical, &data.physical);') + print(' data.index=Logical[0];') + print(' data.size=size;') + print(' retrace::addRegion(call,data.index,(void*)data.logical,size);') + print(' }') + print(' else // already have one; check size and index') + print(' {') + print(' if((size!=data.size)||(Logical[0]!=data.index))') + print(' {') + print(' retrace::delRegionByPointer((void*)data.logical);') + print(' free_dma_buffer(data.privateData);') + print(' data.privateData = alloc_dma_buffer(size, &data.logical, &data.physical);') + print(' data.index=Logical[0];') + print(' data.size=size;') + print(' retrace::addRegion(call,data.index,(void*)data.logical,size);') + print(' }') + print(' }') + print(' *Logical = data.logical;') + print(' *Physical = data.physical;') + print(' }') + print('#endif /* HAVE_VIVANTE_G2D */') # Infer the drawable size from GL calls if function.name == "glViewport": print(' glretrace::updateDrawable(x + width, y + height);') @@ -268,6 +321,54 @@ def invokeFunction(self, function): print(r' currentContext->insideBeginEnd = false;') print(r' }') + if function.name == "glTexDirectVIV": + print('#if defined(HAVE_VIVANTE_G2D)') + print(' int32_t ysize = 0;') + print(' int32_t usize = 0;') + print(' int32_t vsize = 0;') + print(' switch(format){') + print(' case GL_VIV_YV12:') + print(' case GL_VIV_I420:') + print(' ysize=width * height;') + print(' usize=ysize/4;') + print(' vsize=usize;') + print(' break;') + print(' case GL_VIV_NV12:') + print(' case GL_VIV_NV21:') + print(' ysize=width * height;') + print(' usize=ysize/2;') + print(' vsize=0;') + print(' break;') + print(' case GL_RGBA:') + print(' case GL_BGRA_EXT:') + print(' ysize=width * height *4;') + print(' usize=0;') + print(' vsize=0;') + print(' break;') + print(' case GL_RGB:') + print(' ysize=width * height *3;') + print(' usize=0;') + print(' vsize=0;') + print(' break;') + print(' case GL_VIV_YUY2:') + print(' case GL_VIV_UYVY:') + print(' case GL_RGB565_OES:') + print(' ysize=width * height *2;') + print(' usize=0;') + print(' vsize=0;') + print(' break;') + print(' default:') + print(' break;') + print(' }') + print(' const trace::Array * arrayGLvoid = (call.arg(4)).toArray();') + print(' if(ysize > 0)') + print(' retrace::addRegion(call,(*arrayGLvoid->values[0]).toUInt(),(GLvoid*)pixels[0], ysize);') + print(' if(usize > 0)') + print(' retrace::addRegion(call,(*arrayGLvoid->values[1]).toUInt(),(GLvoid*)pixels[1], usize);') + print(' if(vsize > 0)') + print(' retrace::addRegion(call,(*arrayGLvoid->values[2]).toUInt(),(GLvoid*)pixels[2], vsize);') + print('#endif /* HAVE_VIVANTE_G2D */') + if function.name == 'memcpy': print(' if (!dest || !src || !n) return;') @@ -636,6 +737,47 @@ def extractArg(self, function, arg, arg_type, lvalue, rvalue): static void _validateActiveProgram(trace::Call &call); +#if defined(HAVE_VIVANTE_G2D) + +#define GL_VIV_YV12 0x8FC0 +#define GL_VIV_NV12 0x8FC1 +#define GL_VIV_YUY2 0x8FC2 +#define GL_VIV_UYVY 0x8FC3 +#define GL_VIV_NV21 0x8FC4 +#define GL_VIV_I420 0x8FC5 + +typedef struct TexDirectVivData +{ + GLuint logical; // used for glTexDirectVIVMap/glTexDirectMapVIV/glTexDirectTiledMapVIV + GLuint physical; + GLuint index; + uint32_t size; + void *privateData; // used to allocate buffer +}TEXDIRECTVIVDATA; + +static std::map _directTextureDataMap; + +#include + +static void * alloc_dma_buffer(int size, unsigned int *logical, unsigned int *physical) +{ + struct g2d_buf *buf = g2d_alloc(size, 0); + if(buf != NULL) + { + *logical = (unsigned int)buf->buf_vaddr; + *physical = (unsigned int)buf->buf_paddr ; + } + return buf; +} + +static void free_dma_buffer(void *buf) +{ + if(buf != NULL) + g2d_free((g2d_buf *)buf); +} + +#endif /* HAVE_VIVANTE_G2D */ + ''') api = stdapi.API() api.addModule(glapi.glapi) diff --git a/specs/glapi.py b/specs/glapi.py index c7d47eb6..cc8024dc 100644 --- a/specs/glapi.py +++ b/specs/glapi.py @@ -3674,4 +3674,11 @@ def OutGlString(charType, lengthPtr, argName): # GL_WIN_swap_hint GlFunction(Void, "glAddSwapHintRectWIN", [(GLint, "x"), (GLint, "y"), (GLsizei, "width"), (GLsizei, "height")]), + # Vivante extension + GlFunction(Void, "glTexDirectVIV", [(GLenum, "target"), (GLsizei, "width"), (GLsizei, "height"), (GLenum, "format"), Out(Array(GLuint, 3), "pixels")]), + GlFunction(Void, "glTexDirectVIVMap", [(GLenum, "target"), (GLsizei, "width"), (GLsizei, "height"), (GLenum, "format"), (Pointer(GLuint), "Logical"), (Pointer(Const(GLuint)), "Physical")]), + GlFunction(Void, "glTexDirectMapVIV", [(GLenum, "target"), (GLsizei, "width"), (GLsizei, "height"), (GLenum, "format"), (Pointer(GLuint), "Logical"), (Pointer(Const(GLuint)), "Physical")]), + GlFunction(Void, "glTexDirectTiledMapVIV", [(GLenum, "target"), (GLsizei, "width"), (GLsizei, "height"), (GLenum, "format"), (Pointer(GLuint), "Logical"), (Pointer(Const(GLuint)), "Physical")]), + GlFunction(Void, "glTexDirectInvalidateVIV", [(GLenum, "target")]), + ]) diff --git a/wrappers/egltrace.py b/wrappers/egltrace.py index 72317149..6d8fc2c3 100644 --- a/wrappers/egltrace.py +++ b/wrappers/egltrace.py @@ -49,11 +49,109 @@ def isFunctionPublic(self, function): ] def traceFunctionImplBody(self, function): + if function.name == 'glTexDirectMapVIV': + print(' // prevent loop call') + print(' glTexDirectVIVMap(target, width, height, format, Logical, Physical);') + return + + if function.name == 'glTexDirectInvalidateVIV': + print(' // get current texture') + print(' GLint tex = 0;') + print(' int32_t size = 0;') + print(' int32_t ysize = 0;') + print(' int32_t usize = 0;') + print(' int32_t vsize = 0;') + print(' _glGetIntegerv(GL_TEXTURE_BINDING_2D, &tex);') + print(' if(tex == 0)') + print(' {') + print(' return;') + print(' }') + print(' TEXDIRECTVIVDATA &data = _directTextureDataMap[tex];') + print(' switch(data.format){') + print(' case GL_VIV_YV12:') + print(' case GL_VIV_I420:') + print(' ysize=data.width * data.height;') + print(' usize=ysize/4;') + print(' vsize=usize;') + print(' break;') + print(' case GL_VIV_NV12:') + print(' case GL_VIV_NV21:') + print(' ysize=data.width * data.height;') + print(' usize=ysize/2;') + print(' vsize=0;') + print(' break;') + print(' case GL_RGBA:') + print(' case GL_BGRA_EXT:') + print(' ysize=data.width * data.height *4;') + print(' usize=0;') + print(' vsize=0;') + print(' break;') + print(' case GL_RGB:') + print(' ysize=data.width * data.height *3;') + print(' usize=0;') + print(' vsize=0;') + print(' break;') + print(' case GL_VIV_YUY2:') + print(' case GL_VIV_UYVY:') + print(' case GL_RGB565_OES:') + print(' ysize=data.width * data.height *2;') + print(' usize=0;') + print(' vsize=0;') + print(' break;') + print(' default:') + print(' return;') + print(' }') + print(' if (NULL==(GLvoid*)data.logical) {') + print(' if (ysize > 0) {') + self.emit_memcpy('(GLvoid*)data.planes[0]', 'ysize') + print(' }') + print(' if (usize > 0) {') + self.emit_memcpy('(GLvoid*)data.planes[1]', 'usize') + print(' }') + print(' if (vsize > 0) {') + self.emit_memcpy('(GLvoid*)data.planes[2]', 'vsize') + print(' }') + print(' } else {') + print(' size = ysize + usize + vsize;') + print(' if (size > 0) {') + self.emit_memcpy('(GLvoid*)data.logical', 'size') + print(' }') + print(' }') + if function.name == 'eglGetProcAddress': print(' procname = __get_alias_func_name(procname);') GlTracer.traceFunctionImplBody(self, function) + if function.name == 'glTexDirectVIV': + print(' // get current texture') + print(' GLint tex = 0;') + print(' _glGetIntegerv(GL_TEXTURE_BINDING_2D, &tex);') + print(' if(tex != 0)') + print(' {') + print(' TEXDIRECTVIVDATA &data = _directTextureDataMap[tex];') + print(' data.width = width;') + print(' data.height = height;') + print(' data.format = format;') + print(' data.planes[0] = pixels[0];') + print(' data.planes[1] = pixels[1];') + print(' data.planes[2] = pixels[2];') + print(' }') + + if function.name == 'glTexDirectVIVMap' or function.name == 'glTexDirectTiledMapVIV': + print(' // get current texture') + print(' GLint tex = 0;') + print(' _glGetIntegerv(GL_TEXTURE_BINDING_2D, &tex);') + print(' if(tex != 0)') + print(' {') + print(' TEXDIRECTVIVDATA &data = _directTextureDataMap[tex];') + print(' data.width = width;') + print(' data.height = height;') + print(' data.format = format;') + print(' data.logical = *Logical; // Logical != NULL') + print(' data.physical = *Physical;') + print(' }') + if function.name == 'eglCreateContext': print(' if (_result != EGL_NO_CONTEXT)') print(' gltrace::createContext((uintptr_t)_result, (uintptr_t)share_context);') @@ -158,6 +256,27 @@ def traceFunctionImplBody(self, function): print(' return origFunName;') print('}') + print() + print('typedef struct TexDirectVivData') + print('{') + print(' int width;') + print(' int height;') + print(' GLenum format;') + print(' GLuint planes[3]; // used for glTexDirectVIV') + print(' GLuint logical; // used for glTexDirectVIVMap/glTexDirectMapVIV/glTexDirectTiledMapVIV') + print(' GLuint physical;') + print('}TEXDIRECTVIVDATA;') + print() + print('static std::map _directTextureDataMap;') + print() + print('#define GL_VIV_YV12 0x8FC0') + print('#define GL_VIV_NV12 0x8FC1') + print('#define GL_VIV_YUY2 0x8FC2') + print('#define GL_VIV_UYVY 0x8FC3') + print('#define GL_VIV_NV21 0x8FC4') + print('#define GL_VIV_I420 0x8FC5') + print() + module = Module() module.mergeModule(eglapi) module.mergeModule(glapi)