| OLD | NEW | 
| (Empty) |  | 
 |    1  | 
 |    2 /* | 
 |    3  * Copyright 2013 Google Inc. | 
 |    4  * | 
 |    5  * Use of this source code is governed by a BSD-style license that can be | 
 |    6  * found in the LICENSE file. | 
 |    7  */ | 
 |    8 #include "GLContext.h" | 
 |    9 #include "gl/GrGLUtil.h" | 
 |   10 #include "SkGpuFenceSync.h" | 
 |   11  | 
 |   12 namespace sk_gpu_test { | 
 |   13 class GLContext::GLFenceSync : public SkGpuFenceSync { | 
 |   14 public: | 
 |   15     static GLFenceSync* CreateIfSupported(const GLContext*); | 
 |   16  | 
 |   17     SkPlatformGpuFence SK_WARN_UNUSED_RESULT insertFence() const override; | 
 |   18     bool waitFence(SkPlatformGpuFence fence, bool flush) const override; | 
 |   19     void deleteFence(SkPlatformGpuFence fence) const override; | 
 |   20  | 
 |   21 private: | 
 |   22     GLFenceSync() {} | 
 |   23  | 
 |   24     static const GrGLenum GL_SYNC_GPU_COMMANDS_COMPLETE  = 0x9117; | 
 |   25     static const GrGLenum GL_WAIT_FAILED                 = 0x911d; | 
 |   26     static const GrGLbitfield GL_SYNC_FLUSH_COMMANDS_BIT = 0x00000001; | 
 |   27  | 
 |   28     typedef struct __GLsync *GLsync; | 
 |   29  | 
 |   30     typedef GLsync (GR_GL_FUNCTION_TYPE* GLFenceSyncProc) (GrGLenum, GrGLbitfiel
     d); | 
 |   31     typedef GrGLenum (GR_GL_FUNCTION_TYPE* GLClientWaitSyncProc) (GLsync, GrGLbi
     tfield, GrGLuint64); | 
 |   32     typedef GrGLvoid (GR_GL_FUNCTION_TYPE* GLDeleteSyncProc) (GLsync); | 
 |   33  | 
 |   34     GLFenceSyncProc        fGLFenceSync; | 
 |   35     GLClientWaitSyncProc   fGLClientWaitSync; | 
 |   36     GLDeleteSyncProc       fGLDeleteSync; | 
 |   37  | 
 |   38     typedef SkGpuFenceSync INHERITED; | 
 |   39 }; | 
 |   40  | 
 |   41 GLContext::GLContext() | 
 |   42     : fCurrentFenceIdx(0) { | 
 |   43     memset(fFrameFences, 0, sizeof(fFrameFences)); | 
 |   44 } | 
 |   45  | 
 |   46 GLContext::~GLContext() { | 
 |   47     // Subclass should call teardown. | 
 |   48 #ifdef SK_DEBUG | 
 |   49     for (size_t i = 0; i < SK_ARRAY_COUNT(fFrameFences); i++) { | 
 |   50         SkASSERT(0 == fFrameFences[i]); | 
 |   51     } | 
 |   52 #endif | 
 |   53     SkASSERT(nullptr == fGL.get()); | 
 |   54     SkASSERT(nullptr == fFenceSync.get()); | 
 |   55 } | 
 |   56  | 
 |   57 void GLContext::init(const GrGLInterface* gl, SkGpuFenceSync* fenceSync) { | 
 |   58     SkASSERT(!fGL.get()); | 
 |   59     fGL.reset(gl); | 
 |   60     fFenceSync.reset(fenceSync ? fenceSync : GLFenceSync::CreateIfSupported(this
     )); | 
 |   61 } | 
 |   62  | 
 |   63 void GLContext::teardown() { | 
 |   64     if (fFenceSync) { | 
 |   65         for (size_t i = 0; i < SK_ARRAY_COUNT(fFrameFences); i++) { | 
 |   66             if (fFrameFences[i]) { | 
 |   67                 fFenceSync->deleteFence(fFrameFences[i]); | 
 |   68                 fFrameFences[i] = 0; | 
 |   69             } | 
 |   70         } | 
 |   71         fFenceSync.reset(nullptr); | 
 |   72     } | 
 |   73  | 
 |   74     fGL.reset(nullptr); | 
 |   75 } | 
 |   76  | 
 |   77 void GLContext::makeCurrent() const { | 
 |   78     this->onPlatformMakeCurrent(); | 
 |   79 } | 
 |   80  | 
 |   81 void GLContext::swapBuffers() { | 
 |   82     this->onPlatformSwapBuffers(); | 
 |   83 } | 
 |   84  | 
 |   85 void GLContext::waitOnSyncOrSwap() { | 
 |   86     if (!fFenceSync) { | 
 |   87         // Fallback on the platform SwapBuffers method for synchronization. This
      may have no effect. | 
 |   88         this->swapBuffers(); | 
 |   89         return; | 
 |   90     } | 
 |   91  | 
 |   92     if (fFrameFences[fCurrentFenceIdx]) { | 
 |   93         if (!fFenceSync->waitFence(fFrameFences[fCurrentFenceIdx], true)) { | 
 |   94             SkDebugf("WARNING: Wait failed for fence sync. Timings might not be 
     accurate.\n"); | 
 |   95         } | 
 |   96         fFenceSync->deleteFence(fFrameFences[fCurrentFenceIdx]); | 
 |   97     } | 
 |   98  | 
 |   99     fFrameFences[fCurrentFenceIdx] = fFenceSync->insertFence(); | 
 |  100     fCurrentFenceIdx = (fCurrentFenceIdx + 1) % SK_ARRAY_COUNT(fFrameFences); | 
 |  101 } | 
 |  102  | 
 |  103 void GLContext::testAbandon() { | 
 |  104     if (fGL) { | 
 |  105         fGL->abandon(); | 
 |  106     } | 
 |  107     if (fFenceSync) { | 
 |  108         memset(fFrameFences, 0, sizeof(fFrameFences)); | 
 |  109     } | 
 |  110 } | 
 |  111  | 
 |  112 GLContext::GLFenceSync* GLContext::GLFenceSync::CreateIfSupported(const GLContex
     t* ctx) { | 
 |  113     SkAutoTDelete<GLFenceSync> ret(new GLFenceSync); | 
 |  114  | 
 |  115     if (kGL_GrGLStandard == ctx->gl()->fStandard) { | 
 |  116         const GrGLubyte* versionStr; | 
 |  117         GR_GL_CALL_RET(ctx->gl(), versionStr, GetString(GR_GL_VERSION)); | 
 |  118         GrGLVersion version = GrGLGetVersionFromString(reinterpret_cast<const ch
     ar*>(versionStr)); | 
 |  119         if (version < GR_GL_VER(3,2) && !ctx->gl()->hasExtension("GL_ARB_sync"))
      { | 
 |  120             return nullptr; | 
 |  121         } | 
 |  122         ret->fGLFenceSync = reinterpret_cast<GLFenceSyncProc>( | 
 |  123             ctx->onPlatformGetProcAddress("glFenceSync")); | 
 |  124         ret->fGLClientWaitSync = reinterpret_cast<GLClientWaitSyncProc>( | 
 |  125             ctx->onPlatformGetProcAddress("glClientWaitSync")); | 
 |  126         ret->fGLDeleteSync = reinterpret_cast<GLDeleteSyncProc>( | 
 |  127             ctx->onPlatformGetProcAddress("glDeleteSync")); | 
 |  128     } else { | 
 |  129         if (!ctx->gl()->hasExtension("GL_APPLE_sync")) { | 
 |  130             return nullptr; | 
 |  131         } | 
 |  132         ret->fGLFenceSync = reinterpret_cast<GLFenceSyncProc>( | 
 |  133             ctx->onPlatformGetProcAddress("glFenceSyncAPPLE")); | 
 |  134         ret->fGLClientWaitSync = reinterpret_cast<GLClientWaitSyncProc>( | 
 |  135             ctx->onPlatformGetProcAddress("glClientWaitSyncAPPLE")); | 
 |  136         ret->fGLDeleteSync = reinterpret_cast<GLDeleteSyncProc>( | 
 |  137             ctx->onPlatformGetProcAddress("glDeleteSyncAPPLE")); | 
 |  138     } | 
 |  139  | 
 |  140     if (!ret->fGLFenceSync || !ret->fGLClientWaitSync || !ret->fGLDeleteSync) { | 
 |  141         return nullptr; | 
 |  142     } | 
 |  143  | 
 |  144     return ret.release(); | 
 |  145 } | 
 |  146  | 
 |  147 SkPlatformGpuFence GLContext::GLFenceSync::insertFence() const { | 
 |  148     return fGLFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0); | 
 |  149 } | 
 |  150  | 
 |  151 bool GLContext::GLFenceSync::waitFence(SkPlatformGpuFence fence, bool flush) con
     st { | 
 |  152     GLsync glsync = static_cast<GLsync>(fence); | 
 |  153     return GL_WAIT_FAILED != fGLClientWaitSync(glsync, flush ? GL_SYNC_FLUSH_COM
     MANDS_BIT : 0, -1); | 
 |  154 } | 
 |  155  | 
 |  156 void GLContext::GLFenceSync::deleteFence(SkPlatformGpuFence fence) const { | 
 |  157     GLsync glsync = static_cast<GLsync>(fence); | 
 |  158     fGLDeleteSync(glsync); | 
 |  159 } | 
 |  160  | 
 |  161 GrGLint GLContext::createTextureRectangle(int width, int height, GrGLenum intern
     alFormat, | 
 |  162                                           GrGLenum externalFormat, GrGLenum exte
     rnalType, | 
 |  163                                           GrGLvoid* data) { | 
 |  164     if (!(kGL_GrGLStandard == fGL->fStandard && GrGLGetVersion(fGL) >= GR_GL_VER
     (3, 1)) && | 
 |  165         !fGL->fExtensions.has("GL_ARB_texture_rectangle")) { | 
 |  166         return 0; | 
 |  167     } | 
 |  168  | 
 |  169     if  (GrGLGetGLSLVersion(fGL) < GR_GLSL_VER(1, 40)) { | 
 |  170         return 0; | 
 |  171     } | 
 |  172  | 
 |  173     GrGLuint id; | 
 |  174     GR_GL_CALL(fGL, GenTextures(1, &id)); | 
 |  175     GR_GL_CALL(fGL, BindTexture(GR_GL_TEXTURE_RECTANGLE, id)); | 
 |  176     GR_GL_CALL(fGL, TexParameteri(GR_GL_TEXTURE_RECTANGLE, GR_GL_TEXTURE_MAG_FIL
     TER, | 
 |  177                                   GR_GL_NEAREST)); | 
 |  178     GR_GL_CALL(fGL, TexParameteri(GR_GL_TEXTURE_RECTANGLE, GR_GL_TEXTURE_MIN_FIL
     TER, | 
 |  179                                   GR_GL_NEAREST)); | 
 |  180     GR_GL_CALL(fGL, TexParameteri(GR_GL_TEXTURE_RECTANGLE, GR_GL_TEXTURE_WRAP_S, | 
 |  181                                   GR_GL_CLAMP_TO_EDGE));     | 
 |  182     GR_GL_CALL(fGL, TexParameteri(GR_GL_TEXTURE_RECTANGLE, GR_GL_TEXTURE_WRAP_T, | 
 |  183                                   GR_GL_CLAMP_TO_EDGE)); | 
 |  184     GR_GL_CALL(fGL, TexImage2D(GR_GL_TEXTURE_RECTANGLE, 0, internalFormat, width
     , height, 0, | 
 |  185                                externalFormat, externalType, data)); | 
 |  186     return id; | 
 |  187 } | 
 |  188 }  // namespace sk_gpu_test | 
| OLD | NEW |