| OLD | NEW |
| 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 "content/browser/compositor/io_surface_texture_mac.h" | 5 #include "content/browser/compositor/io_surface_texture_mac.h" |
| 6 | 6 |
| 7 #include <OpenGL/CGLIOSurface.h> | 7 #include <OpenGL/CGLIOSurface.h> |
| 8 #include <OpenGL/CGLRenderers.h> | 8 #include <OpenGL/CGLRenderers.h> |
| 9 #include <OpenGL/OpenGL.h> | 9 #include <OpenGL/OpenGL.h> |
| 10 #include <OpenGL/gl.h> | 10 #include <OpenGL/gl.h> |
| (...skipping 17 matching lines...) Expand all Loading... |
| 28 #include "third_party/skia/include/core/SkBitmap.h" | 28 #include "third_party/skia/include/core/SkBitmap.h" |
| 29 #include "ui/gfx/rect.h" | 29 #include "ui/gfx/rect.h" |
| 30 #include "ui/gfx/scoped_ns_graphics_context_save_gstate_mac.h" | 30 #include "ui/gfx/scoped_ns_graphics_context_save_gstate_mac.h" |
| 31 #include "ui/gfx/size_conversions.h" | 31 #include "ui/gfx/size_conversions.h" |
| 32 #include "ui/gl/gl_context.h" | 32 #include "ui/gl/gl_context.h" |
| 33 | 33 |
| 34 namespace content { | 34 namespace content { |
| 35 | 35 |
| 36 // static | 36 // static |
| 37 scoped_refptr<IOSurfaceTexture> IOSurfaceTexture::Create() { | 37 scoped_refptr<IOSurfaceTexture> IOSurfaceTexture::Create() { |
| 38 scoped_refptr<IOSurfaceContext> context = IOSurfaceContext::Get(); | 38 scoped_refptr<IOSurfaceContext> offscreen_context = |
| 39 if (!context.get()) { | 39 IOSurfaceContext::Get( |
| 40 IOSurfaceContext::kOffscreenContext); |
| 41 if (!offscreen_context.get()) { |
| 40 LOG(ERROR) << "Failed to create context for offscreen operations"; | 42 LOG(ERROR) << "Failed to create context for offscreen operations"; |
| 41 return NULL; | 43 return NULL; |
| 42 } | 44 } |
| 43 | 45 |
| 44 return new IOSurfaceTexture(context); | 46 return new IOSurfaceTexture(offscreen_context); |
| 45 } | 47 } |
| 46 | 48 |
| 47 IOSurfaceTexture::IOSurfaceTexture( | 49 IOSurfaceTexture::IOSurfaceTexture( |
| 48 const scoped_refptr<IOSurfaceContext>& context) | 50 const scoped_refptr<IOSurfaceContext>& offscreen_context) |
| 49 : context_(context), | 51 : offscreen_context_(offscreen_context), |
| 50 texture_(0), | 52 texture_(0), |
| 51 gl_error_(GL_NO_ERROR), | 53 gl_error_(GL_NO_ERROR), |
| 52 eviction_queue_iterator_(eviction_queue_.Get().end()), | 54 eviction_queue_iterator_(eviction_queue_.Get().end()), |
| 53 eviction_has_been_drawn_since_updated_(false) { | 55 eviction_has_been_drawn_since_updated_(false) { |
| 54 CHECK(context_.get()); | 56 CHECK(offscreen_context_.get()); |
| 55 } | 57 } |
| 56 | 58 |
| 57 IOSurfaceTexture::~IOSurfaceTexture() { | 59 IOSurfaceTexture::~IOSurfaceTexture() { |
| 58 ReleaseIOSurfaceAndTexture(); | 60 ReleaseIOSurfaceAndTexture(); |
| 59 context_ = NULL; | 61 offscreen_context_ = NULL; |
| 60 DCHECK(eviction_queue_iterator_ == eviction_queue_.Get().end()); | 62 DCHECK(eviction_queue_iterator_ == eviction_queue_.Get().end()); |
| 61 } | 63 } |
| 62 | 64 |
| 63 bool IOSurfaceTexture::DrawIOSurface() { | 65 bool IOSurfaceTexture::DrawIOSurface() { |
| 64 TRACE_EVENT0("browser", "IOSurfaceTexture::DrawIOSurface"); | 66 TRACE_EVENT0("browser", "IOSurfaceTexture::DrawIOSurface"); |
| 65 | 67 |
| 66 // If we have release the IOSurface, clear the screen to light grey and | 68 // If we have release the IOSurface, clear the screen to light grey and |
| 67 // early-out. | 69 // early-out. |
| 68 if (!io_surface_) { | 70 if (!io_surface_) { |
| 69 glClearColor(0.9, 0.9, 0.9, 1); | 71 glClearColor(0.9, 0.9, 0.9, 1); |
| (...skipping 95 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 165 | 167 |
| 166 // Actual IOSurface size is rounded up to reduce reallocations during window | 168 // Actual IOSurface size is rounded up to reduce reallocations during window |
| 167 // resize. Get the actual size to properly map the texture. | 169 // resize. Get the actual size to properly map the texture. |
| 168 gfx::Size rounded_size(IOSurfaceGetWidth(io_surface_), | 170 gfx::Size rounded_size(IOSurfaceGetWidth(io_surface_), |
| 169 IOSurfaceGetHeight(io_surface_)); | 171 IOSurfaceGetHeight(io_surface_)); |
| 170 | 172 |
| 171 // Create the GL texture and set it to be backed by the IOSurface. | 173 // Create the GL texture and set it to be backed by the IOSurface. |
| 172 CGLError cgl_error = kCGLNoError; | 174 CGLError cgl_error = kCGLNoError; |
| 173 { | 175 { |
| 174 gfx::ScopedCGLSetCurrentContext scoped_set_current_context( | 176 gfx::ScopedCGLSetCurrentContext scoped_set_current_context( |
| 175 context_->cgl_context()); | 177 offscreen_context_->cgl_context()); |
| 176 glGenTextures(1, &texture_); | 178 glGenTextures(1, &texture_); |
| 177 glBindTexture(GL_TEXTURE_RECTANGLE_ARB, texture_); | 179 glBindTexture(GL_TEXTURE_RECTANGLE_ARB, texture_); |
| 178 glTexParameterf( | 180 glTexParameterf( |
| 179 GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MIN_FILTER, GL_NEAREST); | 181 GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MIN_FILTER, GL_NEAREST); |
| 180 glTexParameterf( | 182 glTexParameterf( |
| 181 GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MAG_FILTER, GL_NEAREST); | 183 GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MAG_FILTER, GL_NEAREST); |
| 182 cgl_error = CGLTexImageIOSurface2D( | 184 cgl_error = CGLTexImageIOSurface2D( |
| 183 context_->cgl_context(), | 185 offscreen_context_->cgl_context(), |
| 184 GL_TEXTURE_RECTANGLE_ARB, | 186 GL_TEXTURE_RECTANGLE_ARB, |
| 185 GL_RGBA, | 187 GL_RGBA, |
| 186 rounded_size.width(), | 188 rounded_size.width(), |
| 187 rounded_size.height(), | 189 rounded_size.height(), |
| 188 GL_BGRA, | 190 GL_BGRA, |
| 189 GL_UNSIGNED_INT_8_8_8_8_REV, | 191 GL_UNSIGNED_INT_8_8_8_8_REV, |
| 190 io_surface_.get(), | 192 io_surface_.get(), |
| 191 0 /* plane */); | 193 0 /* plane */); |
| 192 glBindTexture(GL_TEXTURE_RECTANGLE_ARB, 0); | 194 glBindTexture(GL_TEXTURE_RECTANGLE_ARB, 0); |
| 193 GetAndSaveGLError(); | 195 GetAndSaveGLError(); |
| 194 } | 196 } |
| 195 | 197 |
| 196 // Return failure if an error was encountered by CGL or GL. | 198 // Return failure if an error was encountered by CGL or GL. |
| 197 if (cgl_error != kCGLNoError) { | 199 if (cgl_error != kCGLNoError) { |
| 198 LOG(ERROR) << "CGLTexImageIOSurface2D failed with CGL error: " << cgl_error; | 200 LOG(ERROR) << "CGLTexImageIOSurface2D failed with CGL error: " << cgl_error; |
| 199 return false; | 201 return false; |
| 200 } | 202 } |
| 201 if (gl_error_ != GL_NO_ERROR) { | 203 if (gl_error_ != GL_NO_ERROR) { |
| 202 LOG(ERROR) << "Hit GL error in SetIOSurface: " << gl_error_; | 204 LOG(ERROR) << "Hit GL error in SetIOSurface: " << gl_error_; |
| 203 return false; | 205 return false; |
| 204 } | 206 } |
| 205 | 207 |
| 206 ignore_result(error_runner.Release()); | 208 ignore_result(error_runner.Release()); |
| 207 return true; | 209 return true; |
| 208 } | 210 } |
| 209 | 211 |
| 210 void IOSurfaceTexture::ReleaseIOSurfaceAndTexture() { | 212 void IOSurfaceTexture::ReleaseIOSurfaceAndTexture() { |
| 211 gfx::ScopedCGLSetCurrentContext scoped_set_current_context( | 213 gfx::ScopedCGLSetCurrentContext scoped_set_current_context( |
| 212 context_->cgl_context()); | 214 offscreen_context_->cgl_context()); |
| 213 | 215 |
| 214 if (texture_) { | 216 if (texture_) { |
| 215 glDeleteTextures(1, &texture_); | 217 glDeleteTextures(1, &texture_); |
| 216 texture_ = 0; | 218 texture_ = 0; |
| 217 } | 219 } |
| 218 pixel_size_ = gfx::Size(); | 220 pixel_size_ = gfx::Size(); |
| 219 io_surface_.reset(); | 221 io_surface_.reset(); |
| 220 | 222 |
| 221 EvictionMarkEvicted(); | 223 EvictionMarkEvicted(); |
| 222 } | 224 } |
| 223 | 225 |
| 226 bool IOSurfaceTexture::HasBeenPoisoned() const { |
| 227 return offscreen_context_->HasBeenPoisoned(); |
| 228 } |
| 229 |
| 224 GLenum IOSurfaceTexture::GetAndSaveGLError() { | 230 GLenum IOSurfaceTexture::GetAndSaveGLError() { |
| 225 GLenum gl_error = glGetError(); | 231 GLenum gl_error = glGetError(); |
| 226 if (gl_error_ == GL_NO_ERROR) | 232 if (gl_error_ == GL_NO_ERROR) |
| 227 gl_error_ = gl_error; | 233 gl_error_ = gl_error; |
| 228 return gl_error; | 234 return gl_error; |
| 229 } | 235 } |
| 230 | 236 |
| 231 void IOSurfaceTexture::EvictionMarkUpdated() { | 237 void IOSurfaceTexture::EvictionMarkUpdated() { |
| 232 EvictionMarkEvicted(); | 238 EvictionMarkEvicted(); |
| 233 eviction_queue_.Get().push_back(this); | 239 eviction_queue_.Get().push_back(this); |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 282 } | 288 } |
| 283 | 289 |
| 284 // static | 290 // static |
| 285 base::LazyInstance<IOSurfaceTexture::EvictionQueue> | 291 base::LazyInstance<IOSurfaceTexture::EvictionQueue> |
| 286 IOSurfaceTexture::eviction_queue_; | 292 IOSurfaceTexture::eviction_queue_; |
| 287 | 293 |
| 288 // static | 294 // static |
| 289 bool IOSurfaceTexture::eviction_scheduled_ = false; | 295 bool IOSurfaceTexture::eviction_scheduled_ = false; |
| 290 | 296 |
| 291 } // namespace content | 297 } // namespace content |
| OLD | NEW |