test_compositor_host_mac.mm revision 5d1f7b1de12d16ceb2c938c56701a3e8bfa558f7
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
3// found in the LICENSE file.
4
5#include "ui/compositor/test/test_compositor_host.h"
6
7#import <AppKit/NSApplication.h>
8#import <AppKit/NSOpenGL.h>
9#import <AppKit/NSView.h>
10#import <AppKit/NSWindow.h>
11#import <Foundation/NSAutoreleasePool.h>
12
13#include "base/compiler_specific.h"
14#include "base/mac/scoped_nsobject.h"
15#include "base/memory/scoped_ptr.h"
16#include "ui/compositor/compositor.h"
17#include "ui/gfx/rect.h"
18
19// AcceleratedTestView provides an NSView class that delegates drawing to a
20// ui::Compositor delegate, setting up the NSOpenGLContext as required.
21@interface AcceleratedTestView : NSView {
22  ui::Compositor* compositor_;
23}
24// Designated initializer.
25-(id)init;
26-(void)setCompositor:(ui::Compositor*)compositor;
27@end
28
29@implementation AcceleratedTestView
30-(id)init {
31  // The frame will be resized when reparented into the window's view hierarchy.
32  self = [super initWithFrame:NSZeroRect];
33  return self;
34}
35
36-(void)setCompositor:(ui::Compositor*)compositor {
37  compositor_ = compositor;
38}
39
40- (void)drawRect:(NSRect)rect {
41  DCHECK(compositor_) << "Drawing with no compositor set.";
42  compositor_->Draw();
43}
44@end
45
46namespace ui {
47
48// Tests that use Objective-C memory semantics need to have a top-level
49// NSAutoreleasePool set up and initialized prior to execution and drained upon
50// exit.  The tests will leak otherwise.
51class FoundationHost {
52 protected:
53  FoundationHost() {
54    pool_ = [[NSAutoreleasePool alloc] init];
55  }
56  virtual ~FoundationHost() {
57    [pool_ drain];
58  }
59
60 private:
61  NSAutoreleasePool* pool_;
62  DISALLOW_COPY_AND_ASSIGN(FoundationHost);
63};
64
65// Tests that use the AppKit framework need to have the NSApplication
66// initialized prior to doing anything with display objects such as windows,
67// views, or controls.
68class AppKitHost : public FoundationHost {
69 protected:
70  AppKitHost() {
71    [NSApplication sharedApplication];
72  }
73  virtual ~AppKitHost() {
74  }
75 private:
76  DISALLOW_COPY_AND_ASSIGN(AppKitHost);
77};
78
79// TestCompositorHostMac provides a window surface and a coordinated compositor
80// for use in the compositor unit tests.
81class TestCompositorHostMac : public TestCompositorHost,
82                              public AppKitHost {
83 public:
84  TestCompositorHostMac(const gfx::Rect& bounds);
85  virtual ~TestCompositorHostMac();
86
87 private:
88  // TestCompositorHost:
89  virtual void Show() OVERRIDE;
90  virtual ui::Compositor* GetCompositor() OVERRIDE;
91
92  gfx::Rect bounds_;
93  scoped_ptr<ui::Compositor> compositor_;
94
95  // Owned.  Released when window is closed.
96  NSWindow* window_;
97
98  DISALLOW_COPY_AND_ASSIGN(TestCompositorHostMac);
99};
100
101TestCompositorHostMac::TestCompositorHostMac(const gfx::Rect& bounds)
102    : bounds_(bounds), window_(nil) {
103}
104
105TestCompositorHostMac::~TestCompositorHostMac() {
106  // Release reference to |compositor_|.  Important because the |compositor_|
107  // holds |this| as its delegate, so that reference must be removed here.
108  [[window_ contentView] setCompositor:NULL];
109  [window_ setContentView:nil];
110
111  [window_ orderOut:nil];
112  [window_ close];
113}
114
115void TestCompositorHostMac::Show() {
116  DCHECK(!window_);
117  window_ = [[NSWindow alloc]
118                initWithContentRect:NSMakeRect(bounds_.x(),
119                                               bounds_.y(),
120                                               bounds_.width(),
121                                               bounds_.height())
122                          styleMask:NSBorderlessWindowMask
123                            backing:NSBackingStoreBuffered
124                              defer:NO];
125  base::scoped_nsobject<AcceleratedTestView> view(
126      [[AcceleratedTestView alloc] init]);
127  compositor_.reset(new ui::Compositor(view));
128  compositor_->SetScaleAndSize(1.0f, bounds_.size());
129  [view setCompositor:compositor_.get()];
130  [window_ setContentView:view];
131  [window_ orderFront:nil];
132}
133
134ui::Compositor* TestCompositorHostMac::GetCompositor() {
135  return compositor_.get();
136}
137
138// static
139TestCompositorHost* TestCompositorHost::Create(const gfx::Rect& bounds) {
140  return new TestCompositorHostMac(bounds);
141}
142
143}  // namespace ui
144