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
3// found in the LICENSE file.
4
5#include "content/browser/compositor/software_layer_mac.h"
6
7#include "base/debug/trace_event.h"
8#include "base/mac/mac_util.h"
9#include "base/mac/scoped_cftyperef.h"
10#include "base/mac/sdk_forward_declarations.h"
11#include "ui/base/cocoa/animation_utils.h"
12
13@implementation SoftwareLayer
14
15- (id)init {
16  if (self = [super init]) {
17    [self setBackgroundColor:CGColorGetConstantColor(kCGColorWhite)];
18    [self setAnchorPoint:CGPointMake(0, 0)];
19    // Setting contents gravity is necessary to prevent the layer from being
20    // scaled during dyanmic resizes (especially with devtools open).
21    [self setContentsGravity:kCAGravityTopLeft];
22  }
23  return self;
24}
25
26- (void)setContentsToData:(const void *)data
27             withRowBytes:(size_t)rowBytes
28            withPixelSize:(gfx::Size)pixelSize
29          withScaleFactor:(float)scaleFactor {
30  TRACE_EVENT0("browser", "-[SoftwareLayer setContentsToData]");
31
32  // Disable animating the contents change or the scale factor change.
33  ScopedCAActionDisabler disabler;
34
35  // Set the contents of the software CALayer to be a CGImage with the provided
36  // pixel data. Make a copy of the data before backing the image with them,
37  // because the same buffer will be reused for the next frame.
38  base::ScopedCFTypeRef<CFDataRef> dataCopy(
39      CFDataCreate(NULL,
40                   static_cast<const UInt8 *>(data),
41                   rowBytes * pixelSize.height()));
42  base::ScopedCFTypeRef<CGDataProviderRef> dataProvider(
43      CGDataProviderCreateWithCFData(dataCopy));
44  base::ScopedCFTypeRef<CGImageRef> image(
45      CGImageCreate(pixelSize.width(),
46                    pixelSize.height(),
47                    8,
48                    32,
49                    rowBytes,
50                    base::mac::GetSystemColorSpace(),
51                    kCGImageAlphaPremultipliedFirst | kCGBitmapByteOrder32Host,
52                    dataProvider,
53                    NULL,
54                    false,
55                    kCGRenderingIntentDefault));
56  [self setContents:(id)image.get()];
57  [self setBounds:CGRectMake(
58      0, 0, pixelSize.width() / scaleFactor, pixelSize.height() / scaleFactor)];
59
60  // Set the contents scale of the software CALayer.
61  if ([self respondsToSelector:(@selector(contentsScale))] &&
62      [self respondsToSelector:(@selector(setContentsScale:))] &&
63      [self contentsScale] != scaleFactor) {
64    [self setContentsScale:scaleFactor];
65  }
66}
67
68@end
69