1 // Copyright 2013 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "content/browser/renderer_host/compositing_iosurface_layer_mac.h"
7 #include <CoreFoundation/CoreFoundation.h>
10 #include "base/mac/sdk_forward_declarations.h"
11 #include "content/browser/renderer_host/render_widget_host_impl.h"
12 #include "content/browser/renderer_host/render_widget_host_view_mac.h"
13 #include "content/browser/renderer_host/compositing_iosurface_context_mac.h"
14 #include "content/browser/renderer_host/compositing_iosurface_mac.h"
15 #include "ui/base/cocoa/animation_utils.h"
16 #include "ui/gfx/size_conversions.h"
18 @implementation CompositingIOSurfaceLayer
20 @synthesize context = context_;
22 - (id)initWithRenderWidgetHostViewMac:(content::RenderWidgetHostViewMac*)r {
23 if (self = [super init]) {
24 renderWidgetHostView_ = r;
26 ScopedCAActionDisabler disabler;
27 [self setBackgroundColor:CGColorGetConstantColor(kCGColorWhite)];
28 [self setContentsGravity:kCAGravityTopLeft];
29 [self setFrame:NSRectToCGRect(
30 [renderWidgetHostView_->cocoa_view() bounds])];
31 [self setNeedsDisplay];
32 [self updateScaleFactor];
37 - (void)updateScaleFactor {
38 if (!renderWidgetHostView_ ||
39 ![self respondsToSelector:(@selector(contentsScale))] ||
40 ![self respondsToSelector:(@selector(setContentsScale:))])
43 float current_scale_factor = [self contentsScale];
44 float new_scale_factor = current_scale_factor;
45 if (renderWidgetHostView_->compositing_iosurface_) {
47 renderWidgetHostView_->compositing_iosurface_->scale_factor();
50 if (new_scale_factor == current_scale_factor)
53 ScopedCAActionDisabler disabler;
54 [self setContentsScale:new_scale_factor];
57 - (void)disableCompositing{
58 ScopedCAActionDisabler disabler;
59 [self removeFromSuperlayer];
60 renderWidgetHostView_ = nil;
63 // The remaining methods implement the CAOpenGLLayer interface.
65 - (CGLContextObj)copyCGLContextForPixelFormat:(CGLPixelFormatObj)pixelFormat {
66 if (!renderWidgetHostView_)
69 context_ = renderWidgetHostView_->compositing_iosurface_context_;
73 return context_->cgl_context();
76 - (void)releaseCGLContext:(CGLContextObj)glContext {
80 DCHECK(glContext == context_->cgl_context());
84 - (void)drawInCGLContext:(CGLContextObj)glContext
85 pixelFormat:(CGLPixelFormatObj)pixelFormat
86 forLayerTime:(CFTimeInterval)timeInterval
87 displayTime:(const CVTimeStamp*)timeStamp {
88 TRACE_EVENT0("browser", "CompositingIOSurfaceLayer::drawInCGLContext");
90 if (!context_.get() || !renderWidgetHostView_ ||
91 !renderWidgetHostView_->compositing_iosurface_) {
92 glClearColor(1, 1, 1, 1);
93 glClear(GL_COLOR_BUFFER_BIT);
97 DCHECK(glContext == context_->cgl_context());
99 // Cache a copy of renderWidgetHostView_ because it may be reset if
100 // a software frame is received in GetBackingStore.
101 content::RenderWidgetHostViewMac* cached_view = renderWidgetHostView_;
103 // If a resize is in progress then GetBackingStore request a frame of the
104 // current window size and block until a frame of the right size comes in.
105 // This makes the window content not lag behind the resize (at the cost of
106 // blocking on the browser's main thread).
107 if (cached_view->render_widget_host_) {
108 cached_view->about_to_validate_and_paint_ = true;
109 (void)cached_view->render_widget_host_->GetBackingStore(true);
110 cached_view->about_to_validate_and_paint_ = false;
113 // If a transition to software mode has occurred, this layer should be
114 // removed from the heirarchy now, so don't draw anything.
115 if (!renderWidgetHostView_)
118 gfx::Rect window_rect([self frame]);
119 float window_scale_factor = 1.f;
120 if ([self respondsToSelector:(@selector(contentsScale))])
121 window_scale_factor = [self contentsScale];
123 CGLSetCurrentContext(glContext);
124 if (!renderWidgetHostView_->compositing_iosurface_->DrawIOSurface(
128 renderWidgetHostView_->frame_subscriber(),
130 renderWidgetHostView_->GotAcceleratedCompositingError();