OLD | NEW |
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 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_surface.h" | 5 #include "ui/gl/gl_surface.h" |
6 | 6 |
7 #include "base/logging.h" | 7 #include "base/logging.h" |
8 #include "base/memory/ref_counted.h" | 8 #include "base/memory/ref_counted.h" |
9 #include "ui/gfx/native_widget_types.h" | 9 #include "ui/gfx/native_widget_types.h" |
10 #include "ui/gl/gl_context.h" | 10 #include "ui/gl/gl_context.h" |
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
98 | 98 |
99 DISALLOW_COPY_AND_ASSIGN(GLSurfaceOzoneEGL); | 99 DISALLOW_COPY_AND_ASSIGN(GLSurfaceOzoneEGL); |
100 }; | 100 }; |
101 | 101 |
102 class GL_EXPORT GLSurfaceOzoneSurfaceless : public SurfacelessEGL { | 102 class GL_EXPORT GLSurfaceOzoneSurfaceless : public SurfacelessEGL { |
103 public: | 103 public: |
104 GLSurfaceOzoneSurfaceless(scoped_ptr<ui::SurfaceOzoneEGL> ozone_surface, | 104 GLSurfaceOzoneSurfaceless(scoped_ptr<ui::SurfaceOzoneEGL> ozone_surface, |
105 AcceleratedWidget widget) | 105 AcceleratedWidget widget) |
106 : SurfacelessEGL(gfx::Size()), | 106 : SurfacelessEGL(gfx::Size()), |
107 ozone_surface_(ozone_surface.Pass()), | 107 ozone_surface_(ozone_surface.Pass()), |
108 widget_(widget) {} | 108 widget_(widget), |
| 109 has_implicit_external_sync_( |
| 110 HasEGLExtension("EGL_ARM_implicit_external_sync")) {} |
109 | 111 |
110 bool Initialize() override { | 112 bool Initialize() override { |
111 if (!SurfacelessEGL::Initialize()) | 113 if (!SurfacelessEGL::Initialize()) |
112 return false; | 114 return false; |
113 vsync_provider_ = ozone_surface_->CreateVSyncProvider(); | 115 vsync_provider_ = ozone_surface_->CreateVSyncProvider(); |
114 if (!vsync_provider_) | 116 if (!vsync_provider_) |
115 return false; | 117 return false; |
116 return true; | 118 return true; |
117 } | 119 } |
118 bool Resize(const gfx::Size& size) override { | 120 bool Resize(const gfx::Size& size) override { |
119 if (!ozone_surface_->ResizeNativeWindow(size)) | 121 if (!ozone_surface_->ResizeNativeWindow(size)) |
120 return false; | 122 return false; |
121 | 123 |
122 return SurfacelessEGL::Resize(size); | 124 return SurfacelessEGL::Resize(size); |
123 } | 125 } |
124 bool SwapBuffers() override { | 126 bool SwapBuffers() override { |
125 // TODO: this should be replaced by a fence when supported by the driver. | 127 if (!Flush()) |
126 glFlush(); | 128 return false; |
127 return ozone_surface_->OnSwapBuffers(); | 129 return ozone_surface_->OnSwapBuffers(); |
128 } | 130 } |
129 bool ScheduleOverlayPlane(int z_order, | 131 bool ScheduleOverlayPlane(int z_order, |
130 OverlayTransform transform, | 132 OverlayTransform transform, |
131 GLImage* image, | 133 GLImage* image, |
132 const Rect& bounds_rect, | 134 const Rect& bounds_rect, |
133 const RectF& crop_rect) override { | 135 const RectF& crop_rect) override { |
134 return image->ScheduleOverlayPlane( | 136 return image->ScheduleOverlayPlane( |
135 widget_, z_order, transform, bounds_rect, crop_rect); | 137 widget_, z_order, transform, bounds_rect, crop_rect); |
136 } | 138 } |
137 bool IsOffscreen() override { return false; } | 139 bool IsOffscreen() override { return false; } |
138 VSyncProvider* GetVSyncProvider() override { return vsync_provider_.get(); } | 140 VSyncProvider* GetVSyncProvider() override { return vsync_provider_.get(); } |
139 bool SupportsPostSubBuffer() override { return true; } | 141 bool SupportsPostSubBuffer() override { return true; } |
140 bool PostSubBuffer(int x, int y, int width, int height) override { | 142 bool PostSubBuffer(int x, int y, int width, int height) override { |
141 // The actual sub buffer handling is handled at higher layers. | 143 // The actual sub buffer handling is handled at higher layers. |
142 SwapBuffers(); | 144 SwapBuffers(); |
143 return true; | 145 return true; |
144 } | 146 } |
145 bool SwapBuffersAsync(const SwapCompletionCallback& callback) override { | 147 bool SwapBuffersAsync(const SwapCompletionCallback& callback) override { |
146 // TODO: this should be replaced by a fence when supported by the driver. | 148 if (!Flush()) |
147 glFlush(); | 149 return false; |
148 return ozone_surface_->OnSwapBuffersAsync(callback); | 150 return ozone_surface_->OnSwapBuffersAsync(callback); |
149 } | 151 } |
150 bool PostSubBufferAsync(int x, | 152 bool PostSubBufferAsync(int x, |
151 int y, | 153 int y, |
152 int width, | 154 int width, |
153 int height, | 155 int height, |
154 const SwapCompletionCallback& callback) override { | 156 const SwapCompletionCallback& callback) override { |
155 return SwapBuffersAsync(callback); | 157 return SwapBuffersAsync(callback); |
156 } | 158 } |
157 | 159 |
158 private: | 160 private: |
159 ~GLSurfaceOzoneSurfaceless() override { | 161 ~GLSurfaceOzoneSurfaceless() override { |
160 Destroy(); // EGL surface must be destroyed before SurfaceOzone | 162 Destroy(); // EGL surface must be destroyed before SurfaceOzone |
161 } | 163 } |
162 | 164 |
| 165 bool Flush() { |
| 166 glFlush(); |
| 167 // TODO: the following should be replaced by a per surface flush as it gets |
| 168 // implemented in GL drivers. |
| 169 if (has_implicit_external_sync_) { |
| 170 const EGLint attrib_list[] = { |
| 171 EGL_SYNC_CONDITION_KHR, |
| 172 EGL_SYNC_PRIOR_COMMANDS_IMPLICIT_EXTERNAL_ARM, |
| 173 EGL_NONE}; |
| 174 EGLSyncKHR fence = |
| 175 eglCreateSyncKHR(GetDisplay(), EGL_SYNC_FENCE_KHR, attrib_list); |
| 176 if (fence) { |
| 177 // TODO(dbehr): piman@ suggests we could improve here by moving |
| 178 // following wait to right before drmModePageFlip crbug.com/456417. |
| 179 eglClientWaitSyncKHR(GetDisplay(), fence, |
| 180 EGL_SYNC_FLUSH_COMMANDS_BIT_KHR, EGL_FOREVER_KHR); |
| 181 eglDestroySyncKHR(GetDisplay(), fence); |
| 182 } else { |
| 183 return false; |
| 184 } |
| 185 } |
| 186 return true; |
| 187 } |
| 188 |
163 // The native surface. Deleting this is allowed to free the EGLNativeWindow. | 189 // The native surface. Deleting this is allowed to free the EGLNativeWindow. |
164 scoped_ptr<ui::SurfaceOzoneEGL> ozone_surface_; | 190 scoped_ptr<ui::SurfaceOzoneEGL> ozone_surface_; |
165 AcceleratedWidget widget_; | 191 AcceleratedWidget widget_; |
166 scoped_ptr<VSyncProvider> vsync_provider_; | 192 scoped_ptr<VSyncProvider> vsync_provider_; |
167 | 193 bool has_implicit_external_sync_; |
168 DISALLOW_COPY_AND_ASSIGN(GLSurfaceOzoneSurfaceless); | 194 DISALLOW_COPY_AND_ASSIGN(GLSurfaceOzoneSurfaceless); |
169 }; | 195 }; |
170 | 196 |
171 } // namespace | 197 } // namespace |
172 | 198 |
173 // static | 199 // static |
174 bool GLSurface::InitializeOneOffInternal() { | 200 bool GLSurface::InitializeOneOffInternal() { |
175 switch (GetGLImplementation()) { | 201 switch (GetGLImplementation()) { |
176 case kGLImplementationEGLGLES2: | 202 case kGLImplementationEGLGLES2: |
177 if (!GLSurfaceEGL::InitializeOneOff()) { | 203 if (!GLSurfaceEGL::InitializeOneOff()) { |
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
257 NOTREACHED(); | 283 NOTREACHED(); |
258 return NULL; | 284 return NULL; |
259 } | 285 } |
260 } | 286 } |
261 | 287 |
262 EGLNativeDisplayType GetPlatformDefaultEGLNativeDisplay() { | 288 EGLNativeDisplayType GetPlatformDefaultEGLNativeDisplay() { |
263 return ui::SurfaceFactoryOzone::GetInstance()->GetNativeDisplay(); | 289 return ui::SurfaceFactoryOzone::GetInstance()->GetNativeDisplay(); |
264 } | 290 } |
265 | 291 |
266 } // namespace gfx | 292 } // namespace gfx |
OLD | NEW |