| 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
|
| index 7531297ece8d113cb366b8fbc4a922d835efcde4..ed8d3535cb9b26b90db5ac9d441c9a77c6a1e124 100644
|
| --- a/content/common/gpu/image_transport_surface_calayer_mac.mm
|
| +++ b/content/common/gpu/image_transport_surface_calayer_mac.mm
|
| @@ -4,13 +4,10 @@
|
|
|
| #include "content/common/gpu/image_transport_surface_calayer_mac.h"
|
|
|
| -#include "base/command_line.h"
|
| #include "base/mac/sdk_forward_declarations.h"
|
| #include "content/common/gpu/surface_handle_types_mac.h"
|
| #include "ui/base/cocoa/animation_utils.h"
|
| #include "ui/gfx/geometry/size_conversions.h"
|
| -#include "ui/gl/gl_gl_api_implementation.h"
|
| -#include "ui/gl/gl_switches.h"
|
|
|
| @interface ImageTransportLayer : CAOpenGLLayer {
|
| content::CALayerStorageProvider* storageProvider_;
|
| @@ -29,8 +26,6 @@
|
| }
|
|
|
| - (void)resetStorageProvider {
|
| - if (storageProvider_)
|
| - storageProvider_->LayerResetStorageProvider();
|
| storageProvider_ = NULL;
|
| }
|
|
|
| @@ -65,10 +60,6 @@
|
| 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();
|
| } else {
|
| @@ -88,13 +79,17 @@
|
| CALayerStorageProvider::CALayerStorageProvider(
|
| ImageTransportSurfaceFBO* transport_surface)
|
| : transport_surface_(transport_surface),
|
| - gpu_vsync_disabled_(CommandLine::ForCurrentProcess()->HasSwitch(
|
| - switches::kDisableGpuVsync)),
|
| has_pending_draw_(false),
|
| can_draw_returned_false_count_(0),
|
| - fbo_texture_(0),
|
| - fbo_scale_factor_(1),
|
| - weak_factory_(this) {}
|
| + fbo_texture_(0) {
|
| + // Allocate a CAContext to use to transport the CALayer to the browser
|
| + // process.
|
| + base::scoped_nsobject<NSDictionary> dict([[NSDictionary alloc] init]);
|
| + CGSConnectionID connection_id = CGSMainConnectionID();
|
| + context_.reset([CAContext contextWithCGSConnection:connection_id
|
| + options:dict]);
|
| + [context_ retain];
|
| +}
|
|
|
| CALayerStorageProvider::~CALayerStorageProvider() {
|
| }
|
| @@ -131,12 +126,15 @@
|
| // Disable the fade-in animation as the layer is changed.
|
| ScopedCAActionDisabler disabler;
|
|
|
| - // Set the parameters that will be used to allocate the CALayer to draw the
|
| - // texture into.
|
| + // Allocate a CALayer to draw texture into.
|
| share_group_context_.reset(CGLRetainContext(context));
|
| fbo_texture_ = texture;
|
| fbo_pixel_size_ = pixel_size;
|
| - fbo_scale_factor_ = scale_factor;
|
| + layer_.reset([[ImageTransportLayer alloc] initWithStorageProvider:this]);
|
| + gfx::Size dip_size(gfx::ToFlooredSize(gfx::ScaleSize(
|
| + fbo_pixel_size_, 1.0f / scale_factor)));
|
| + [layer_ setContentsScale:scale_factor];
|
| + [layer_ setFrame:CGRectMake(0, 0, dip_size.width(), dip_size.height())];
|
| return true;
|
| }
|
|
|
| @@ -157,78 +155,25 @@
|
| fbo_pixel_size_ = gfx::Size();
|
| }
|
|
|
| -void CALayerStorageProvider::SwapBuffers(
|
| - const gfx::Size& size, float scale_factor) {
|
| +uint64 CALayerStorageProvider::GetSurfaceHandle() const {
|
| + return SurfaceHandleFromCAContextID([context_ contextId]);
|
| +}
|
| +
|
| +void CALayerStorageProvider::WillSwapBuffers() {
|
| DCHECK(!has_pending_draw_);
|
| has_pending_draw_ = true;
|
|
|
| - // Allocate a CAContext to use to transport the CALayer to the browser
|
| - // process.
|
| - if (!context_) {
|
| - base::scoped_nsobject<NSDictionary> dict([[NSDictionary alloc] init]);
|
| - CGSConnectionID connection_id = CGSMainConnectionID();
|
| - context_.reset([CAContext contextWithCGSConnection:connection_id
|
| - options:dict]);
|
| - [context_ retain];
|
| - }
|
| -
|
| - // Allocate a CALayer to use to draw the content.
|
| - if (!layer_) {
|
| - layer_.reset([[ImageTransportLayer alloc] initWithStorageProvider:this]);
|
| - gfx::Size dip_size(gfx::ToFlooredSize(gfx::ScaleSize(
|
| - fbo_pixel_size_, 1.0f / fbo_scale_factor_)));
|
| - [layer_ setContentsScale:fbo_scale_factor_];
|
| - [layer_ setFrame:CGRectMake(0, 0, dip_size.width(), dip_size.height())];
|
| -
|
| - // Make the CALayer current to the CAContext and display its contents
|
| - // immediately.
|
| + // Don't add the layer to the CAContext until a SwapBuffers is going to be
|
| + // called, because the texture does not have any content until the
|
| + // SwapBuffers call is about to be made.
|
| + if ([context_ layer] != layer_.get())
|
| [context_ setLayer:layer_];
|
| - }
|
| -
|
| - // Tell CoreAnimation to draw our frame. We will send the IPC to the browser
|
| - // when CoreAnimation has drawn our frame.
|
| - if (gpu_vsync_disabled_) {
|
| - DrawWithVsyncDisabled();
|
| - } else {
|
| - if (![layer_ isAsynchronous])
|
| - [layer_ setAsynchronous:YES];
|
| - }
|
| -}
|
| -
|
| -void CALayerStorageProvider::DrawWithVsyncDisabled() {
|
| - DCHECK(has_pending_draw_);
|
| - [layer_ setNeedsDisplay];
|
| -
|
| - // Sometimes, setNeedsDisplay calls are dropped on the floor. Make this not
|
| - // hang the renderer by re-issuing the call if the draw has not yet
|
| - // happened.
|
| - if (has_pending_draw_) {
|
| - // Delay sending another draw immediately to avoid starving the run loop.
|
| - base::MessageLoop::current()->PostDelayedTask(
|
| - FROM_HERE,
|
| - base::Bind(&CALayerStorageProvider::DrawWithVsyncDisabled,
|
| - weak_factory_.GetWeakPtr()),
|
| - base::TimeDelta::FromMilliseconds(5));
|
| - }
|
| -}
|
| -
|
| -void CALayerStorageProvider::WillWriteToBackbuffer() {
|
| - // TODO(ccameron): The browser may need to continue issuing swaps even when
|
| - // they do not draw. In these cases it is necessary to either double-buffer
|
| - // the resulting texture, or to drop frames.
|
| -}
|
| -
|
| -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.
|
| - [layer_ resetStorageProvider];
|
| - layer_.reset();
|
| - context_.reset();
|
| -}
|
| -
|
| -void CALayerStorageProvider::SwapBuffersAckedByBrowser() {
|
| +
|
| + if (![layer_ isAsynchronous])
|
| + [layer_ setAsynchronous:YES];
|
| +}
|
| +
|
| +void CALayerStorageProvider::CanFreeSwappedBuffer() {
|
| }
|
|
|
| CGLContextObj CALayerStorageProvider::LayerShareGroupContext() {
|
| @@ -240,22 +185,20 @@
|
| can_draw_returned_false_count_ = 0;
|
| return true;
|
| } else {
|
| - if ([layer_ isAsynchronous]) {
|
| - DCHECK(!gpu_vsync_disabled_);
|
| - // 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 30 of these in
|
| - // a row, ask that we stop getting these callback for now, so that we
|
| - // don't waste CPU cycles.
|
| - if (can_draw_returned_false_count_ == 30)
|
| + if (can_draw_returned_false_count_ == 30) {
|
| + if ([layer_ isAsynchronous])
|
| [layer_ setAsynchronous:NO];
|
| - else
|
| - can_draw_returned_false_count_ += 1;
|
| + } else {
|
| + can_draw_returned_false_count_ += 1;
|
| }
|
| return false;
|
| }
|
| }
|
|
|
| void CALayerStorageProvider::LayerDoDraw() {
|
| + DCHECK(has_pending_draw_);
|
| + has_pending_draw_ = false;
|
| +
|
| GLint viewport[4] = {0, 0, 0, 0};
|
| glGetIntegerv(GL_VIEWPORT, viewport);
|
| gfx::Size viewport_size(viewport[2], viewport[3]);
|
| @@ -290,25 +233,7 @@
|
| glDisable(GL_TEXTURE_RECTANGLE_ARB);
|
|
|
| // Allow forward progress in the context now that the swap is complete.
|
| - DCHECK(has_pending_draw_);
|
| - SendPendingSwapToBrowserAfterFrameDrawn();
|
| -}
|
| -
|
| -void CALayerStorageProvider::LayerResetStorageProvider() {
|
| - // If we are providing back-pressure by waiting for a draw, that draw will
|
| - // now never come, so release the pressure now.
|
| - SendPendingSwapToBrowserAfterFrameDrawn();
|
| -}
|
| -
|
| -void CALayerStorageProvider::SendPendingSwapToBrowserAfterFrameDrawn() {
|
| - if (!has_pending_draw_)
|
| - return;
|
| - weak_factory_.InvalidateWeakPtrs();
|
| - has_pending_draw_ = false;
|
| - transport_surface_->SendSwapBuffers(
|
| - SurfaceHandleFromCAContextID([context_ contextId]),
|
| - fbo_pixel_size_,
|
| - fbo_scale_factor_);
|
| + transport_surface_->UnblockContextAfterPendingSwap();
|
| }
|
|
|
| } // namespace content
|
|
|