Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(8)

Side by Side Diff: ui/gl/gl_fence.cc

Issue 180723023: gpu: Mailbox emulation with EGLImage (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: oops Created 6 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "ui/gl/gl_fence.h" 5 #include "ui/gl/gl_fence.h"
6 6
7 #include "base/compiler_specific.h" 7 #include "base/compiler_specific.h"
8 #include "ui/gl/gl_bindings.h" 8 #include "ui/gl/gl_bindings.h"
9 #include "ui/gl/gl_context.h" 9 #include "ui/gl/gl_context.h"
10 10
11 namespace { 11 namespace {
12 12
13 class GLFenceNVFence: public gfx::GLFence { 13 class GLFenceNVFence: public gfx::GLFence {
14 public: 14 public:
15 GLFenceNVFence() { 15 GLFenceNVFence(bool flush) {
16 // What if either of these GL calls fails? TestFenceNV will return true. 16 // What if either of these GL calls fails? TestFenceNV will return true.
17 // See spec: 17 // See spec:
18 // http://www.opengl.org/registry/specs/NV/fence.txt 18 // http://www.opengl.org/registry/specs/NV/fence.txt
19 // 19 //
20 // What should happen if TestFenceNV is called for a name before SetFenceNV 20 // What should happen if TestFenceNV is called for a name before SetFenceNV
21 // is called? 21 // is called?
22 // We generate an INVALID_OPERATION error, and return TRUE. 22 // We generate an INVALID_OPERATION error, and return TRUE.
23 // This follows the semantics for texture object names before 23 // This follows the semantics for texture object names before
24 // they are bound, in that they acquire their state upon binding. 24 // they are bound, in that they acquire their state upon binding.
25 // We will arbitrarily return TRUE for consistency. 25 // We will arbitrarily return TRUE for consistency.
26 glGenFencesNV(1, &fence_); 26 glGenFencesNV(1, &fence_);
27 glSetFenceNV(fence_, GL_ALL_COMPLETED_NV); 27 glSetFenceNV(fence_, GL_ALL_COMPLETED_NV);
28 glFlush(); 28 if (flush)
29 glFlush();
29 } 30 }
30 31
31 virtual bool HasCompleted() OVERRIDE { 32 virtual bool HasCompleted() OVERRIDE {
32 return !!glTestFenceNV(fence_); 33 return !!glTestFenceNV(fence_);
33 } 34 }
34 35
35 virtual void ClientWait() OVERRIDE { 36 virtual void ClientWait() OVERRIDE {
36 glFinishFenceNV(fence_); 37 glFinishFenceNV(fence_);
37 } 38 }
38 39
40 virtual void ServerWait() OVERRIDE {
41 glFinishFenceNV(fence_);
42 }
43
39 private: 44 private:
40 virtual ~GLFenceNVFence() { 45 virtual ~GLFenceNVFence() {
41 glDeleteFencesNV(1, &fence_); 46 glDeleteFencesNV(1, &fence_);
42 } 47 }
43 48
44 GLuint fence_; 49 GLuint fence_;
45 }; 50 };
46 51
47 class GLFenceARBSync: public gfx::GLFence { 52 class GLFenceARBSync: public gfx::GLFence {
48 public: 53 public:
49 GLFenceARBSync() { 54 GLFenceARBSync(bool flush) {
50 sync_ = glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0); 55 sync_ = glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0);
51 glFlush(); 56 if (flush)
57 glFlush();
52 } 58 }
53 59
54 virtual bool HasCompleted() OVERRIDE { 60 virtual bool HasCompleted() OVERRIDE {
55 // Handle the case where FenceSync failed. 61 // Handle the case where FenceSync failed.
56 if (!sync_) 62 if (!sync_)
57 return true; 63 return true;
58 64
59 // We could potentially use glGetSynciv here, but it doesn't work 65 // We could potentially use glGetSynciv here, but it doesn't work
60 // on OSX 10.7 (always says the fence is not signaled yet). 66 // on OSX 10.7 (always says the fence is not signaled yet).
61 // glClientWaitSync works better, so let's use that instead. 67 // glClientWaitSync works better, so let's use that instead.
62 return glClientWaitSync(sync_, 0, 0) != GL_TIMEOUT_EXPIRED; 68 return glClientWaitSync(sync_, 0, 0) != GL_TIMEOUT_EXPIRED;
63 } 69 }
64 70
65 virtual void ClientWait() OVERRIDE { 71 virtual void ClientWait() OVERRIDE {
66 glClientWaitSync(sync_, GL_SYNC_FLUSH_COMMANDS_BIT, GL_TIMEOUT_IGNORED); 72 glClientWaitSync(sync_, GL_SYNC_FLUSH_COMMANDS_BIT, GL_TIMEOUT_IGNORED);
67 } 73 }
68 74
75 virtual void ServerWait() OVERRIDE {
76 glWaitSync(sync_, 0, GL_TIMEOUT_IGNORED);
77 }
78
69 private: 79 private:
70 virtual ~GLFenceARBSync() { 80 virtual ~GLFenceARBSync() {
71 glDeleteSync(sync_); 81 glDeleteSync(sync_);
72 } 82 }
73 83
74 GLsync sync_; 84 GLsync sync_;
75 }; 85 };
76 86
77 #if !defined(OS_MACOSX) 87 #if !defined(OS_MACOSX)
78 class EGLFenceSync : public gfx::GLFence { 88 class EGLFenceSync : public gfx::GLFence {
79 public: 89 public:
80 EGLFenceSync() { 90 EGLFenceSync(bool flush) {
81 display_ = eglGetCurrentDisplay(); 91 display_ = eglGetCurrentDisplay();
82 sync_ = eglCreateSyncKHR(display_, EGL_SYNC_FENCE_KHR, NULL); 92 sync_ = eglCreateSyncKHR(display_, EGL_SYNC_FENCE_KHR, NULL);
83 glFlush(); 93 if (flush)
94 glFlush();
84 } 95 }
85 96
86 virtual bool HasCompleted() OVERRIDE { 97 virtual bool HasCompleted() OVERRIDE {
87 EGLint value = 0; 98 EGLint value = 0;
88 eglGetSyncAttribKHR(display_, sync_, EGL_SYNC_STATUS_KHR, &value); 99 eglGetSyncAttribKHR(display_, sync_, EGL_SYNC_STATUS_KHR, &value);
89 DCHECK(value == EGL_SIGNALED_KHR || value == EGL_UNSIGNALED_KHR); 100 DCHECK(value == EGL_SIGNALED_KHR || value == EGL_UNSIGNALED_KHR);
90 return !value || value == EGL_SIGNALED_KHR; 101 return !value || value == EGL_SIGNALED_KHR;
91 } 102 }
92 103
93 virtual void ClientWait() OVERRIDE { 104 virtual void ClientWait() OVERRIDE {
94 EGLint flags = 0; 105 EGLint flags = 0;
95 EGLTimeKHR time = EGL_FOREVER_KHR; 106 EGLTimeKHR time = EGL_FOREVER_KHR;
96 eglClientWaitSyncKHR(display_, sync_, flags, time); 107 eglClientWaitSyncKHR(display_, sync_, flags, time);
97 } 108 }
98 109
110 virtual void ServerWait() OVERRIDE {
111 EGLint flags = 0;
112 eglWaitSyncKHR(display_, sync_, flags);
113 }
114
115
99 private: 116 private:
100 virtual ~EGLFenceSync() { 117 virtual ~EGLFenceSync() {
101 eglDestroySyncKHR(display_, sync_); 118 eglDestroySyncKHR(display_, sync_);
102 } 119 }
103 120
104 EGLSyncKHR sync_; 121 EGLSyncKHR sync_;
105 EGLDisplay display_; 122 EGLDisplay display_;
106 }; 123 };
107 #endif // !OS_MACOSX 124 #endif // !OS_MACOSX
108 125
126 // static
127 gfx::GLFence* CreateFence(bool flush) {
128 #if !defined(OS_MACOSX)
129 if (gfx::g_driver_egl.ext.b_EGL_KHR_fence_sync)
130 return new EGLFenceSync(flush);
131 #endif
132 if (gfx::g_driver_gl.ext.b_GL_NV_fence)
133 return new GLFenceNVFence(flush);
134 if (gfx::g_driver_gl.ext.b_GL_ARB_sync)
135 return new GLFenceARBSync(flush);
piman 2014/03/13 04:41:58 Because the NV_fence implementation degrades to a
no sievers 2014/03/13 20:50:15 Done in https://codereview.chromium.org/195763015
136 return NULL;
137 }
138
109 } // namespace 139 } // namespace
110 140
111 namespace gfx { 141 namespace gfx {
112 142
113 GLFence::GLFence() { 143 GLFence::GLFence() {
114 } 144 }
115 145
116 GLFence::~GLFence() { 146 GLFence::~GLFence() {
117 } 147 }
118 148
119 // static
120 GLFence* GLFence::Create() { 149 GLFence* GLFence::Create() {
121 #if !defined(OS_MACOSX) 150 return CreateFence(true);
122 if (gfx::g_driver_egl.ext.b_EGL_KHR_fence_sync) 151 }
123 return new EGLFenceSync(); 152
124 #endif 153 GLFence* GLFence::CreateWithoutFlush() {
125 if (gfx::g_driver_gl.ext.b_GL_NV_fence) 154 return CreateFence(false);
126 return new GLFenceNVFence();
127 if (gfx::g_driver_gl.ext.b_GL_ARB_sync)
128 return new GLFenceARBSync();
129 return NULL;
130 } 155 }
131 156
132 } // namespace gfx 157 } // namespace gfx
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698