| Index: content/common/gpu/image_transport_surface_calayer_mac.mm | 
| diff --git a/content/common/gpu/image_transport_surface_calayer_mac.mm b/content/common/gpu/image_transport_surface_calayer_mac.mm | 
| deleted file mode 100644 | 
| index a9e5a976af9ae6a4a1bdd327c2ca3fa8ff7862bd..0000000000000000000000000000000000000000 | 
| --- a/content/common/gpu/image_transport_surface_calayer_mac.mm | 
| +++ /dev/null | 
| @@ -1,649 +0,0 @@ | 
| -// Copyright 2014 The Chromium Authors. All rights reserved. | 
| -// Use of this source code is governed by a BSD-style license that can be | 
| -// found in the LICENSE file. | 
| - | 
| -#include "content/common/gpu/image_transport_surface_calayer_mac.h" | 
| - | 
| -#include <IOSurface/IOSurface.h> | 
| -#include <OpenGL/CGLRenderers.h> | 
| -#include <OpenGL/CGLIOSurface.h> | 
| - | 
| -#include "base/command_line.h" | 
| -#include "base/mac/sdk_forward_declarations.h" | 
| -#include "base/trace_event/trace_event.h" | 
| -#include "gpu/config/gpu_info_collector.h" | 
| -#include "ui/accelerated_widget_mac/surface_handle_types.h" | 
| -#include "ui/base/cocoa/animation_utils.h" | 
| -#include "ui/gfx/geometry/dip_util.h" | 
| -#include "ui/gfx/geometry/size_conversions.h" | 
| -#include "ui/gl/gl_switches.h" | 
| -#include "ui/gl/gpu_switching_manager.h" | 
| -#include "ui/gl/scoped_api.h" | 
| - | 
| -namespace { | 
| -const size_t kFramesToKeepCAContextAfterDiscard = 2; | 
| -const size_t kCanDrawFalsesBeforeSwitchFromAsync = 4; | 
| -const base::TimeDelta kMinDeltaToSwitchToAsync = | 
| -    base::TimeDelta::FromSecondsD(1. / 15.); | 
| - | 
| - | 
| -}  // namespace | 
| - | 
| -@interface ImageTransportCAOpenGLLayer : CAOpenGLLayer { | 
| -  content::CALayerStorageProvider* storageProvider_; | 
| -  base::Closure didDrawCallback_; | 
| - | 
| -  // Used to determine if we should use setNeedsDisplay or setAsynchronous to | 
| -  // animate. If the last swap time happened very recently, then | 
| -  // setAsynchronous is used (which allows smooth animation, but comes with the | 
| -  // penalty of the canDrawInCGLContext function waking up the process every | 
| -  // vsync). | 
| -  base::TimeTicks lastSynchronousSwapTime_; | 
| - | 
| -  // A counter that is incremented whenever LayerCanDraw returns false. If this | 
| -  // reaches a threshold, then |layer_| is switched to synchronous drawing to | 
| -  // save CPU work. | 
| -  uint32 canDrawReturnedFalseCount_; | 
| - | 
| -  gfx::Size pixelSize_; | 
| -} | 
| - | 
| -- (id)initWithStorageProvider:(content::CALayerStorageProvider*)storageProvider | 
| -                    pixelSize:(gfx::Size)pixelSize | 
| -                  scaleFactor:(float)scaleFactor; | 
| -- (void)requestDrawNewFrame; | 
| -- (void)drawPendingFrameImmediately; | 
| -- (void)resetStorageProvider; | 
| -@end | 
| - | 
| -@implementation ImageTransportCAOpenGLLayer | 
| - | 
| -- (id)initWithStorageProvider: | 
| -    (content::CALayerStorageProvider*)storageProvider | 
| -                    pixelSize:(gfx::Size)pixelSize | 
| -                  scaleFactor:(float)scaleFactor { | 
| -  if (self = [super init]) { | 
| -    gfx::Size dipSize = gfx::ConvertSizeToDIP(scaleFactor, pixelSize); | 
| -    [self setContentsScale:scaleFactor]; | 
| -    [self setFrame:CGRectMake(0, 0, dipSize.width(), dipSize.height())]; | 
| -    storageProvider_ = storageProvider; | 
| -    pixelSize_ = pixelSize; | 
| -  } | 
| -  return self; | 
| -} | 
| - | 
| -- (void)requestDrawNewFrame { | 
| -  // This tracing would be more natural to do with a pseudo-thread for each | 
| -  // layer, rather than a counter. | 
| -  // http://crbug.com/366300 | 
| -  // A trace value of 2 indicates that there is a pending swap ack. See | 
| -  // canDrawInCGLContext for other value meanings. | 
| -  TRACE_COUNTER_ID1("gpu", "CALayerPendingSwap", self, 2); | 
| - | 
| -  if (![self isAsynchronous]) { | 
| -    // Switch to asynchronous drawing only if we get two frames in rapid | 
| -    // succession. | 
| -    base::TimeTicks this_swap_time = base::TimeTicks::Now(); | 
| -    base::TimeDelta delta = this_swap_time - lastSynchronousSwapTime_; | 
| -    if (delta <= kMinDeltaToSwitchToAsync) { | 
| -      lastSynchronousSwapTime_ = base::TimeTicks(); | 
| -      [self setAsynchronous:YES]; | 
| -    } else { | 
| -      lastSynchronousSwapTime_ = this_swap_time; | 
| -      [self setNeedsDisplay]; | 
| -    } | 
| -  } | 
| -} | 
| - | 
| -- (void)drawPendingFrameImmediately { | 
| -  DCHECK(storageProvider_->LayerHasPendingDraw()); | 
| -  if ([self isAsynchronous]) | 
| -    [self setAsynchronous:NO]; | 
| -  [self setNeedsDisplay]; | 
| -  [self displayIfNeeded]; | 
| -} | 
| - | 
| -- (void)resetStorageProvider { | 
| -  storageProvider_ = NULL; | 
| -} | 
| - | 
| -- (CGLPixelFormatObj)copyCGLPixelFormatForDisplayMask:(uint32_t)mask { | 
| -  if (!storageProvider_) | 
| -    return NULL; | 
| -  return CGLRetainPixelFormat(CGLGetPixelFormat( | 
| -      storageProvider_->LayerShareGroupContext())); | 
| -} | 
| - | 
| -- (CGLContextObj)copyCGLContextForPixelFormat:(CGLPixelFormatObj)pixelFormat { | 
| -  if (!storageProvider_) | 
| -    return NULL; | 
| -  CGLContextObj context = NULL; | 
| -  CGLError error = CGLCreateContext( | 
| -      pixelFormat, storageProvider_->LayerShareGroupContext(), &context); | 
| -  if (error != kCGLNoError) | 
| -    LOG(ERROR) << "CGLCreateContext failed with CGL error: " << error; | 
| -  return context; | 
| -} | 
| - | 
| -- (BOOL)canDrawInCGLContext:(CGLContextObj)glContext | 
| -                pixelFormat:(CGLPixelFormatObj)pixelFormat | 
| -               forLayerTime:(CFTimeInterval)timeInterval | 
| -                displayTime:(const CVTimeStamp*)timeStamp { | 
| -  TRACE_EVENT0("gpu", "CALayerStorageProvider::LayerCanDraw"); | 
| - | 
| -  if (!storageProvider_) | 
| -    return NO; | 
| - | 
| -  if (storageProvider_->LayerHasPendingDraw()) { | 
| -    // If there is a draw pending then increase the signal from 2 to 3, to | 
| -    // indicate that there is a swap pending, and CoreAnimation has asked to | 
| -    // draw it. | 
| -    TRACE_COUNTER_ID1("gpu", "CALayerPendingSwap", self, 3); | 
| - | 
| -    canDrawReturnedFalseCount_ = 0; | 
| -    return YES; | 
| -  } else { | 
| -    // If there is not a draw pending, then give an instantaneous blip up from | 
| -    // 0 to 1, indicating that CoreAnimation was ready to draw a frame but we | 
| -    // were not (or didn't have new content to draw). | 
| -    TRACE_COUNTER_ID1("gpu", "CALayerPendingSwap", self, 1); | 
| -    TRACE_COUNTER_ID1("gpu", "CALayerPendingSwap", self, 0); | 
| - | 
| -    if ([self isAsynchronous]) { | 
| -      // If we are in asynchronous mode, we will be getting callbacks at every | 
| -      // vsync, asking us if we have anything to draw. If we get many of these | 
| -      // in a row, ask that we stop getting these callback for now, so that we | 
| -      // don't waste CPU cycles. | 
| -      if (canDrawReturnedFalseCount_ >= kCanDrawFalsesBeforeSwitchFromAsync) | 
| -        [self setAsynchronous:NO]; | 
| -      else | 
| -        canDrawReturnedFalseCount_ += 1; | 
| -    } | 
| -    return NO; | 
| -  } | 
| -} | 
| - | 
| -- (void)drawInCGLContext:(CGLContextObj)glContext | 
| -             pixelFormat:(CGLPixelFormatObj)pixelFormat | 
| -            forLayerTime:(CFTimeInterval)timeInterval | 
| -             displayTime:(const CVTimeStamp*)timeStamp { | 
| -  // While in this callback, CoreAnimation has set |glContext| to be current. | 
| -  // Ensure that the GL calls that we make are made against the native GL API. | 
| -  gfx::ScopedSetGLToRealGLApi scoped_set_gl_api; | 
| - | 
| -  if (storageProvider_) { | 
| -    storageProvider_->LayerDoDraw(gfx::Rect(pixelSize_), false); | 
| -    storageProvider_->LayerUnblockBrowserIfNeeded(); | 
| -    // A trace value of 0 indicates that there is no longer a pending swap ack. | 
| -    TRACE_COUNTER_ID1("gpu", "CALayerPendingSwap", self, 0); | 
| -  } else { | 
| -    glClearColor(1, 1, 1, 1); | 
| -    glClear(GL_COLOR_BUFFER_BIT); | 
| -  } | 
| -  [super drawInCGLContext:glContext | 
| -              pixelFormat:pixelFormat | 
| -             forLayerTime:timeInterval | 
| -              displayTime:timeStamp]; | 
| -} | 
| - | 
| -@end | 
| - | 
| -namespace content { | 
| - | 
| -CALayerStorageProvider::CALayerStorageProvider( | 
| -    ImageTransportSurfaceFBO* transport_surface) | 
| -    : transport_surface_(transport_surface), | 
| -      gpu_vsync_disabled_(base::CommandLine::ForCurrentProcess()->HasSwitch( | 
| -          switches::kDisableGpuVsync)), | 
| -      throttling_disabled_(false), | 
| -      has_pending_ack_(false), | 
| -      fbo_texture_(0), | 
| -      fbo_scale_factor_(1), | 
| -      program_(0), | 
| -      vertex_shader_(0), | 
| -      fragment_shader_(0), | 
| -      position_location_(0), | 
| -      tex_location_(0), | 
| -      vertex_buffer_(0), | 
| -      vertex_array_(0), | 
| -      recreate_layer_after_gpu_switch_(false), | 
| -      pending_draw_weak_factory_(this) { | 
| -  ui::GpuSwitchingManager::GetInstance()->AddObserver(this); | 
| -} | 
| - | 
| -CALayerStorageProvider::~CALayerStorageProvider() { | 
| -  ui::GpuSwitchingManager::GetInstance()->RemoveObserver(this); | 
| -} | 
| - | 
| -gfx::Size CALayerStorageProvider::GetRoundedSize(gfx::Size size) { | 
| -  return size; | 
| -} | 
| - | 
| -bool CALayerStorageProvider::AllocateColorBufferStorage( | 
| -    CGLContextObj context, const base::Closure& context_dirtied_callback, | 
| -    GLuint texture, gfx::Size pixel_size, float scale_factor) { | 
| -  // Allocate an ordinary OpenGL texture to back the FBO. | 
| -  GLenum error; | 
| -  while ((error = glGetError()) != GL_NO_ERROR) { | 
| -    LOG(ERROR) << "OpenGL error hit but ignored before allocating buffer " | 
| -               << "storage: " << error; | 
| -  } | 
| - | 
| -  if (gfx::GetGLImplementation() == | 
| -      gfx::kGLImplementationDesktopGLCoreProfile) { | 
| -    glTexImage2D(GL_TEXTURE_2D, | 
| -                 0, | 
| -                 GL_RGBA, | 
| -                 pixel_size.width(), | 
| -                 pixel_size.height(), | 
| -                 0, | 
| -                 GL_RGBA, | 
| -                 GL_UNSIGNED_BYTE, | 
| -                 NULL); | 
| -    glFlush(); | 
| - | 
| -    if (!vertex_shader_) { | 
| -      const char* source = | 
| -          "#version 150\n" | 
| -          "in vec4 position;\n" | 
| -          "out vec2 texcoord;\n" | 
| -          "void main() {\n" | 
| -          "    texcoord = vec2(position.x, position.y);\n" | 
| -          "    gl_Position = vec4(2*position.x-1, 2*position.y-1,\n" | 
| -          "        position.z, position.w);\n" | 
| -          "}\n"; | 
| -      vertex_shader_ = glCreateShader(GL_VERTEX_SHADER); | 
| -      glShaderSource(vertex_shader_, 1, &source, NULL); | 
| -      glCompileShader(vertex_shader_); | 
| -#if DCHECK_IS_ON() | 
| -      GLint status = GL_FALSE; | 
| -      glGetShaderiv(vertex_shader_, GL_COMPILE_STATUS, &status); | 
| -      DCHECK(status == GL_TRUE); | 
| -#endif | 
| -    } | 
| -    if (!fragment_shader_) { | 
| -      const char* source = | 
| -          "#version 150\n" | 
| -          "uniform sampler2D tex;\n" | 
| -          "in vec2 texcoord;\n" | 
| -          "out vec4 frag_color;\n" | 
| -          "void main() {\n" | 
| -          "    frag_color = texture(tex, texcoord);\n" | 
| -          "}\n"; | 
| -      fragment_shader_ = glCreateShader(GL_FRAGMENT_SHADER); | 
| -      glShaderSource(fragment_shader_, 1, &source, NULL); | 
| -      glCompileShader(fragment_shader_); | 
| -#if DCHECK_IS_ON() | 
| -      GLint status = GL_FALSE; | 
| -      glGetShaderiv(fragment_shader_, GL_COMPILE_STATUS, &status); | 
| -      DCHECK(status == GL_TRUE); | 
| -#endif | 
| -    } | 
| -    if (!program_) { | 
| -      program_ = glCreateProgram(); | 
| -      glAttachShader(program_, vertex_shader_); | 
| -      glAttachShader(program_, fragment_shader_); | 
| -      glBindFragDataLocation(program_, 0, "frag_color"); | 
| -      glLinkProgram(program_); | 
| -#if DCHECK_IS_ON() | 
| -      GLint status = GL_FALSE; | 
| -      glGetProgramiv(program_, GL_LINK_STATUS, &status); | 
| -      DCHECK(status == GL_TRUE); | 
| -#endif | 
| -      position_location_ = glGetAttribLocation(program_, "position"); | 
| -      tex_location_ = glGetUniformLocation(program_, "tex"); | 
| -    } | 
| -    if (!vertex_buffer_) { | 
| -      GLfloat vertex_data[24] = { | 
| -        0, 0, 0, 1, | 
| -        1, 0, 0, 1, | 
| -        1, 1, 0, 1, | 
| -        1, 1, 0, 1, | 
| -        0, 1, 0, 1, | 
| -        0, 0, 0, 1, | 
| -      }; | 
| -      glGenBuffersARB(1, &vertex_buffer_); | 
| -      // If the allocation path used GLContext::RestoreStateIfDirtiedExternally | 
| -      // as the draw path does, this manual state restoration would not be | 
| -      // necessary. | 
| -      GLint bound_buffer = 0; | 
| -      glGetIntegerv(GL_ARRAY_BUFFER_BINDING, &bound_buffer); | 
| -      glBindBuffer(GL_ARRAY_BUFFER, vertex_buffer_); | 
| -      glBufferData(GL_ARRAY_BUFFER, sizeof(vertex_data), | 
| -                   vertex_data, GL_STATIC_DRAW); | 
| -      glBindBuffer(GL_ARRAY_BUFFER, bound_buffer); | 
| -    } | 
| -    if (!vertex_array_) { | 
| -      // If the allocation path used GLContext::RestoreStateIfDirtiedExternally | 
| -      // as the draw path does, this manual state restoration would not be | 
| -      // necessary. | 
| -      GLint bound_vao = 0; | 
| -      glGetIntegerv(GL_VERTEX_ARRAY_BINDING_OES, &bound_vao); | 
| -      glGenVertexArraysOES(1, &vertex_array_); | 
| -      glBindVertexArrayOES(vertex_array_); | 
| -      { | 
| -        glEnableVertexAttribArray(position_location_); | 
| -        GLint bound_buffer = 0; | 
| -        glGetIntegerv(GL_ARRAY_BUFFER_BINDING, &bound_buffer); | 
| -        glBindBuffer(GL_ARRAY_BUFFER, vertex_buffer_); | 
| -        glVertexAttribPointer(position_location_, 4, GL_FLOAT, GL_FALSE, 0, 0); | 
| -        glBindBuffer(GL_ARRAY_BUFFER, bound_buffer); | 
| -      } | 
| -      glBindVertexArrayOES(bound_vao); | 
| -    } | 
| -  } else { | 
| -    glTexImage2D(GL_TEXTURE_RECTANGLE_ARB, | 
| -                 0, | 
| -                 GL_RGBA, | 
| -                 pixel_size.width(), | 
| -                 pixel_size.height(), | 
| -                 0, | 
| -                 GL_RGBA, | 
| -                 GL_UNSIGNED_BYTE, | 
| -                 NULL); | 
| -    glFlush(); | 
| -  } | 
| - | 
| -  bool hit_error = false; | 
| -  while ((error = glGetError()) != GL_NO_ERROR) { | 
| -    LOG(ERROR) << "OpenGL error hit while trying to allocate buffer storage: " | 
| -               << error; | 
| -    hit_error = true; | 
| -  } | 
| -  if (hit_error) | 
| -    return false; | 
| - | 
| -  // Set the parameters that will be used to allocate the CALayer to draw the | 
| -  // texture into. | 
| -  share_group_context_.reset(CGLRetainContext(context)); | 
| -  share_group_context_dirtied_callback_ = context_dirtied_callback; | 
| -  fbo_texture_ = texture; | 
| -  fbo_pixel_size_ = pixel_size; | 
| -  fbo_scale_factor_ = scale_factor; | 
| -  return true; | 
| -} | 
| - | 
| -void CALayerStorageProvider::FreeColorBufferStorage() { | 
| -  if (gfx::GetGLImplementation() == | 
| -      gfx::kGLImplementationDesktopGLCoreProfile) { | 
| -    if (vertex_shader_) | 
| -      glDeleteShader(vertex_shader_); | 
| -    if (fragment_shader_) | 
| -      glDeleteShader(fragment_shader_); | 
| -    if (program_) | 
| -      glDeleteProgram(program_); | 
| -    if (vertex_buffer_) | 
| -      glDeleteBuffersARB(1, &vertex_buffer_); | 
| -    if (vertex_array_) | 
| -      glDeleteVertexArraysOES(1, &vertex_array_); | 
| -    vertex_shader_ = 0; | 
| -    fragment_shader_ = 0; | 
| -    program_ = 0; | 
| -    vertex_buffer_ = 0; | 
| -    vertex_array_ = 0; | 
| -  } | 
| - | 
| -  // Note that |context_| still holds a reference to |layer_|, and will until | 
| -  // a new frame is swapped in. | 
| -  ResetLayer(); | 
| - | 
| -  share_group_context_.reset(); | 
| -  share_group_context_dirtied_callback_ = base::Closure(); | 
| -  fbo_texture_ = 0; | 
| -  fbo_pixel_size_ = gfx::Size(); | 
| -} | 
| - | 
| -void CALayerStorageProvider::FrameSizeChanged(const gfx::Size& pixel_size, | 
| -                                              float scale_factor) { | 
| -  DCHECK_EQ(fbo_pixel_size_.ToString(), pixel_size.ToString()); | 
| -  DCHECK_EQ(fbo_scale_factor_, scale_factor); | 
| -} | 
| - | 
| -void CALayerStorageProvider::SwapBuffers(const gfx::Rect& dirty_rect) { | 
| -  TRACE_EVENT0("gpu", "CALayerStorageProvider::SwapBuffers"); | 
| -  DCHECK(!has_pending_ack_); | 
| - | 
| -  // Recreate the CALayer on the new GPU if a GPU switch has occurred. Note | 
| -  // that the CAContext will retain a reference to the old CALayer until the | 
| -  // call to -[CAContext setLayer:] replaces the old CALayer with the new one. | 
| -  if (recreate_layer_after_gpu_switch_) { | 
| -    ResetLayer(); | 
| -    recreate_layer_after_gpu_switch_ = false; | 
| -  } | 
| - | 
| -  // Set the pending draw flag only after potentially destroying the old layer | 
| -  // (otherwise destroying it will un-set the flag). | 
| -  has_pending_ack_ = true; | 
| - | 
| -  // Allocate a CAContext to use to transport the CALayer to the browser | 
| -  // process, if needed. | 
| -  if (!context_) { | 
| -    base::scoped_nsobject<NSDictionary> dict([[NSDictionary alloc] init]); | 
| -    CGSConnectionID connection_id = CGSMainConnectionID(); | 
| -    context_.reset([CAContext contextWithCGSConnection:connection_id | 
| -                                               options:dict]); | 
| -    [context_ retain]; | 
| -  } | 
| - | 
| -  // Create the appropriate CALayer (if needed) and request that it draw. | 
| -  bool should_draw_immediately = gpu_vsync_disabled_ || throttling_disabled_; | 
| -  CreateLayerAndRequestDraw(should_draw_immediately, dirty_rect); | 
| - | 
| -  // CoreAnimation may not call the function to un-block the browser in a | 
| -  // timely manner (or ever). Post a task to force the draw and un-block | 
| -  // the browser (at the next cycle through the run-loop if drawing is to | 
| -  // be immediate, and at a timeout of 1/6th of a second otherwise). | 
| -  if (has_pending_ack_) { | 
| -    base::MessageLoop::current()->PostDelayedTask( | 
| -        FROM_HERE, | 
| -        base::Bind(&CALayerStorageProvider::DrawImmediatelyAndUnblockBrowser, | 
| -                   pending_draw_weak_factory_.GetWeakPtr()), | 
| -        should_draw_immediately ? base::TimeDelta() : | 
| -                                  base::TimeDelta::FromSeconds(1) / 6); | 
| -  } | 
| -} | 
| - | 
| -void CALayerStorageProvider::CreateLayerAndRequestDraw( | 
| -    bool should_draw_immediately, const gfx::Rect& dirty_rect) { | 
| -  if (!ca_opengl_layer_) { | 
| -    ca_opengl_layer_.reset([[ImageTransportCAOpenGLLayer alloc] | 
| -        initWithStorageProvider:this | 
| -                      pixelSize:fbo_pixel_size_ | 
| -                    scaleFactor:fbo_scale_factor_]); | 
| -  } | 
| - | 
| -  // -[CAOpenGLLayer drawInCGLContext] won't get called until we're in the | 
| -  // visible layer hierarchy, so call setLayer: immediately, to make this | 
| -  // happen. | 
| -  [context_ setLayer:ca_opengl_layer_]; | 
| - | 
| -  // Tell CoreAnimation to draw our frame. Note that sometimes, calling | 
| -  // -[CAContext setLayer:] will result in the layer getting an immediate | 
| -  // draw. If that happend, we're done. | 
| -  if (!should_draw_immediately && has_pending_ack_) { | 
| -    [ca_opengl_layer_ requestDrawNewFrame]; | 
| -  } | 
| -} | 
| - | 
| -void CALayerStorageProvider::DrawImmediatelyAndUnblockBrowser() { | 
| -  DCHECK(has_pending_ack_); | 
| - | 
| -  if (ca_opengl_layer_) { | 
| -    // Beware that sometimes, the setNeedsDisplay+displayIfNeeded pairs have no | 
| -    // effect. This can happen if the NSView that this layer is attached to | 
| -    // isn't in the window hierarchy (e.g, tab capture of a backgrounded tab). | 
| -    // In this case, the frame will never be seen, so drop it. | 
| -    [ca_opengl_layer_ drawPendingFrameImmediately]; | 
| -  } | 
| - | 
| -  UnblockBrowserIfNeeded(); | 
| -} | 
| - | 
| -void CALayerStorageProvider::WillWriteToBackbuffer() { | 
| -  // The browser should always throttle itself so that there are no pending | 
| -  // draws when the output surface is written to, but in the event of things | 
| -  // like context lost, or changing context, this will not be true. If there | 
| -  // exists a pending draw, flush it immediately to maintain a consistent | 
| -  // state. | 
| -  if (has_pending_ack_) | 
| -    DrawImmediatelyAndUnblockBrowser(); | 
| -} | 
| - | 
| -void CALayerStorageProvider::DiscardBackbuffer() { | 
| -  // If this surface's backbuffer is discarded, it is because this surface has | 
| -  // been made non-visible. Ensure that the previous contents are not briefly | 
| -  // flashed when this is made visible by creating a new CALayer and CAContext | 
| -  // at the next swap. | 
| -  ResetLayer(); | 
| - | 
| -  // If we remove all references to the CAContext in this process, it will be | 
| -  // blanked-out in the browser process (even if the browser process is inside | 
| -  // a disable screen updates block). Ensure that the context is kept around | 
| -  // until a fixed number of frames (determined empirically) have been acked. | 
| -  // http://crbug.com/425819 | 
| -  while (previously_discarded_contexts_.size() < | 
| -      kFramesToKeepCAContextAfterDiscard) { | 
| -    previously_discarded_contexts_.push_back( | 
| -        base::scoped_nsobject<CAContext>()); | 
| -  } | 
| -  previously_discarded_contexts_.push_back(context_); | 
| - | 
| -  context_.reset(); | 
| -} | 
| - | 
| -void CALayerStorageProvider::SwapBuffersAckedByBrowser( | 
| -    bool disable_throttling) { | 
| -  TRACE_EVENT0("gpu", "CALayerStorageProvider::SwapBuffersAckedByBrowser"); | 
| -  throttling_disabled_ = disable_throttling; | 
| -  if (!previously_discarded_contexts_.empty()) | 
| -    previously_discarded_contexts_.pop_front(); | 
| -} | 
| - | 
| -CGLContextObj CALayerStorageProvider::LayerShareGroupContext() { | 
| -  return share_group_context_; | 
| -} | 
| - | 
| -base::Closure CALayerStorageProvider::LayerShareGroupContextDirtiedCallback() { | 
| -  return share_group_context_dirtied_callback_; | 
| -} | 
| - | 
| -void CALayerStorageProvider::LayerDoDraw( | 
| -    const gfx::Rect& dirty_rect, bool flipped) { | 
| -  TRACE_EVENT0("gpu", "CALayerStorageProvider::LayerDoDraw"); | 
| -  if (gfx::GetGLImplementation() == | 
| -      gfx::kGLImplementationDesktopGLCoreProfile) { | 
| -    glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); | 
| -    glClearColor(1, 0, 1, 1); | 
| -    glClear(GL_COLOR_BUFFER_BIT); | 
| -    glDisable(GL_BLEND); | 
| -    glDisable(GL_CULL_FACE); | 
| -    glDisable(GL_DEPTH_TEST); | 
| -    glDisable(GL_STENCIL_TEST); | 
| -    glDisable(GL_SCISSOR_TEST); | 
| - | 
| -    DCHECK(glIsProgram(program_)); | 
| -    glUseProgram(program_); | 
| -    glBindVertexArrayOES(vertex_array_); | 
| - | 
| -    glActiveTexture(GL_TEXTURE0); | 
| -    glBindTexture(GL_TEXTURE_2D, fbo_texture_); | 
| -    glUniform1i(tex_location_, 0); | 
| - | 
| -    glDisable(GL_CULL_FACE); | 
| -    glDrawArrays(GL_TRIANGLES, 0, 6); | 
| -    glBindVertexArrayOES(0); | 
| -    glUseProgram(0); | 
| -  } else { | 
| -    GLint viewport[4] = {0, 0, 0, 0}; | 
| -    glGetIntegerv(GL_VIEWPORT, viewport); | 
| -    gfx::Size viewport_size(viewport[2], viewport[3]); | 
| - | 
| -    // Set the coordinate system to be one-to-one with pixels. | 
| -    glMatrixMode(GL_PROJECTION); | 
| -    glLoadIdentity(); | 
| -    if (flipped) | 
| -      glOrtho(0, viewport_size.width(), viewport_size.height(), 0, -1, 1); | 
| -    else | 
| -      glOrtho(0, viewport_size.width(), 0, viewport_size.height(), -1, 1); | 
| -    glMatrixMode(GL_MODELVIEW); | 
| -    glLoadIdentity(); | 
| - | 
| -    // Reset drawing state and draw a fullscreen quad. | 
| -    glUseProgram(0); | 
| -    glDisable(GL_BLEND); | 
| -    glDisable(GL_CULL_FACE); | 
| -    glDisable(GL_DEPTH_TEST); | 
| -    glDisable(GL_STENCIL_TEST); | 
| -    glDisable(GL_SCISSOR_TEST); | 
| -    glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); | 
| -    glColor4f(1, 1, 1, 1); | 
| -    glActiveTexture(GL_TEXTURE0); | 
| -    glEnable(GL_TEXTURE_RECTANGLE_ARB); | 
| -    glBindTexture(GL_TEXTURE_RECTANGLE_ARB, fbo_texture_); | 
| -    glBegin(GL_QUADS); | 
| -    { | 
| -      glTexCoord2f(dirty_rect.x(), dirty_rect.y()); | 
| -      glVertex2f(dirty_rect.x(), dirty_rect.y()); | 
| - | 
| -      glTexCoord2f(dirty_rect.x(), dirty_rect.bottom()); | 
| -      glVertex2f(dirty_rect.x(), dirty_rect.bottom()); | 
| - | 
| -      glTexCoord2f(dirty_rect.right(), dirty_rect.bottom()); | 
| -      glVertex2f(dirty_rect.right(), dirty_rect.bottom()); | 
| - | 
| -      glTexCoord2f(dirty_rect.right(), dirty_rect.y()); | 
| -      glVertex2f(dirty_rect.right(), dirty_rect.y()); | 
| -    } | 
| -    glEnd(); | 
| -    glBindTexture(GL_TEXTURE_RECTANGLE_ARB, 0); | 
| -    glDisable(GL_TEXTURE_RECTANGLE_ARB); | 
| -  } | 
| - | 
| -  GLint current_renderer_id = 0; | 
| -  if (CGLGetParameter(CGLGetCurrentContext(), | 
| -                      kCGLCPCurrentRendererID, | 
| -                      ¤t_renderer_id) == kCGLNoError) { | 
| -    current_renderer_id &= kCGLRendererIDMatchingMask; | 
| -    transport_surface_->SetRendererID(current_renderer_id); | 
| -  } | 
| - | 
| -  GLenum error; | 
| -  while ((error = glGetError()) != GL_NO_ERROR) { | 
| -    LOG(ERROR) << "OpenGL error hit while drawing frame: " << error; | 
| -  } | 
| -} | 
| - | 
| -void CALayerStorageProvider::LayerUnblockBrowserIfNeeded() { | 
| -  UnblockBrowserIfNeeded(); | 
| -} | 
| - | 
| -bool CALayerStorageProvider::LayerHasPendingDraw() const { | 
| -  return has_pending_ack_; | 
| -} | 
| - | 
| -void CALayerStorageProvider::OnGpuSwitched() { | 
| -  recreate_layer_after_gpu_switch_ = true; | 
| -} | 
| - | 
| -void CALayerStorageProvider::UnblockBrowserIfNeeded() { | 
| -  if (!has_pending_ack_) | 
| -    return; | 
| -  pending_draw_weak_factory_.InvalidateWeakPtrs(); | 
| -  has_pending_ack_ = false; | 
| -  transport_surface_->SendSwapBuffers( | 
| -      ui::SurfaceHandleFromCAContextID([context_ contextId]), | 
| -      fbo_pixel_size_, | 
| -      fbo_scale_factor_); | 
| -} | 
| - | 
| -void CALayerStorageProvider::ResetLayer() { | 
| -  if (ca_opengl_layer_) { | 
| -    [ca_opengl_layer_ resetStorageProvider]; | 
| -    // If we are providing back-pressure by waiting for a draw, that draw will | 
| -    // now never come, so release the pressure now. | 
| -    UnblockBrowserIfNeeded(); | 
| -    ca_opengl_layer_.reset(); | 
| -  } | 
| -} | 
| - | 
| -}  //  namespace content | 
|  |