1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include "ui/gl/gl_fence.h"
6 
7 #include "base/compiler_specific.h"
8 #include "build/build_config.h"
9 #include "ui/gl/gl_bindings.h"
10 #include "ui/gl/gl_context.h"
11 #include "ui/gl/gl_fence_arb.h"
12 #include "ui/gl/gl_fence_egl.h"
13 #include "ui/gl/gl_fence_nv.h"
14 #include "ui/gl/gl_implementation.h"
15 #include "ui/gl/gl_version_info.h"
16 
17 #if defined(OS_APPLE)
18 #include "ui/gl/gl_fence_apple.h"
19 #endif
20 
21 #if defined(USE_EGL) && defined(OS_POSIX) && !defined(OS_APPLE) && !defined(OS_BSD)
22 #define USE_GL_FENCE_ANDROID_NATIVE_FENCE_SYNC
23 #include "ui/gl/gl_fence_android_native_fence_sync.h"
24 #include "ui/gl/gl_surface_egl.h"
25 #endif
26 
27 #if defined(OS_WIN)
28 #include "ui/gl/gl_fence_win.h"
29 #endif
30 
31 namespace gl {
32 
GLFence()33 GLFence::GLFence() {
34 }
35 
~GLFence()36 GLFence::~GLFence() {
37 }
38 
IsSupported()39 bool GLFence::IsSupported() {
40   DCHECK(g_current_gl_version && g_current_gl_driver);
41   return g_current_gl_driver->ext.b_GL_ARB_sync ||
42          g_current_gl_version->is_es3 ||
43          g_current_gl_version->is_desktop_core_profile ||
44 #if defined(OS_APPLE)
45          g_current_gl_driver->ext.b_GL_APPLE_fence ||
46 #else
47          g_driver_egl.ext.b_EGL_KHR_fence_sync ||
48 #endif
49          g_current_gl_driver->ext.b_GL_NV_fence;
50 }
51 
Create()52 std::unique_ptr<GLFence> GLFence::Create() {
53   DCHECK(GLContext::GetCurrent())
54       << "Trying to create fence with no context";
55 
56   std::unique_ptr<GLFence> fence;
57 #if !defined(OS_APPLE)
58   if (g_driver_egl.ext.b_EGL_KHR_fence_sync &&
59       g_driver_egl.ext.b_EGL_KHR_wait_sync) {
60     // Prefer GLFenceEGL which doesn't require GL context switching.
61     fence = GLFenceEGL::Create();
62     DCHECK(fence);
63   } else
64 #endif
65       if (g_current_gl_driver->ext.b_GL_ARB_sync ||
66           g_current_gl_version->is_es3 ||
67           g_current_gl_version->is_desktop_core_profile) {
68     // Prefer ARB_sync which supports server-side wait.
69     fence = std::make_unique<GLFenceARB>();
70 #if defined(OS_APPLE)
71   } else if (g_current_gl_driver->ext.b_GL_APPLE_fence) {
72     fence = std::make_unique<GLFenceAPPLE>();
73 #else
74   } else if (g_driver_egl.ext.b_EGL_KHR_fence_sync) {
75     fence = GLFenceEGL::Create();
76     DCHECK(fence);
77 #endif
78   } else if (g_current_gl_driver->ext.b_GL_NV_fence) {
79     fence = std::make_unique<GLFenceNV>();
80   }
81 
82   DCHECK_EQ(!!fence.get(), GLFence::IsSupported());
83   return fence;
84 }
85 
ResetSupported()86 bool GLFence::ResetSupported() {
87   // Resetting a fence to its original state isn't supported by default.
88   return false;
89 }
90 
ResetState()91 void GLFence::ResetState() {
92   NOTIMPLEMENTED();
93 }
94 
Invalidate()95 void GLFence::Invalidate() {
96   NOTIMPLEMENTED();
97 }
98 
IsGpuFenceSupported()99 bool GLFence::IsGpuFenceSupported() {
100 #if defined(USE_GL_FENCE_ANDROID_NATIVE_FENCE_SYNC)
101   return gl::GLSurfaceEGL::IsAndroidNativeFenceSyncSupported();
102 #elif defined(OS_WIN)
103   return gl::GLFenceWin::IsSupported();
104 #else
105   return false;
106 #endif
107 }
108 
109 // static
CreateFromGpuFence(const gfx::GpuFence & gpu_fence)110 std::unique_ptr<GLFence> GLFence::CreateFromGpuFence(
111     const gfx::GpuFence& gpu_fence) {
112   DCHECK(IsGpuFenceSupported());
113 #if defined(USE_GL_FENCE_ANDROID_NATIVE_FENCE_SYNC)
114   return GLFenceAndroidNativeFenceSync::CreateFromGpuFence(gpu_fence);
115 #elif defined(OS_WIN)
116   return GLFenceWin::CreateFromGpuFence(gpu_fence);
117 #else
118   NOTREACHED();
119   return nullptr;
120 #endif
121 }
122 
123 // static
CreateForGpuFence()124 std::unique_ptr<GLFence> GLFence::CreateForGpuFence() {
125   DCHECK(IsGpuFenceSupported());
126 #if defined(USE_GL_FENCE_ANDROID_NATIVE_FENCE_SYNC)
127   return GLFenceAndroidNativeFenceSync::CreateForGpuFence();
128 #elif defined(OS_WIN)
129   return GLFenceWin::CreateForGpuFence();
130 #else
131   NOTREACHED();
132   return nullptr;
133 #endif
134 }
135 
GetGpuFence()136 std::unique_ptr<gfx::GpuFence> GLFence::GetGpuFence() {
137   return nullptr;
138 }
139 
140 }  // namespace gl
141