test_compositor_host_mac.mm revision cedac228d2dd51db4b79ea1e72c7f249408ee061
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 ui::ContextFactory* context_factory); 86 virtual ~TestCompositorHostMac(); 87 88 private: 89 // TestCompositorHost: 90 virtual void Show() OVERRIDE; 91 virtual ui::Compositor* GetCompositor() OVERRIDE; 92 93 gfx::Rect bounds_; 94 95 ui::ContextFactory* context_factory_; 96 97 scoped_ptr<ui::Compositor> compositor_; 98 99 // Owned. Released when window is closed. 100 NSWindow* window_; 101 102 DISALLOW_COPY_AND_ASSIGN(TestCompositorHostMac); 103}; 104 105TestCompositorHostMac::TestCompositorHostMac( 106 const gfx::Rect& bounds, 107 ui::ContextFactory* context_factory) 108 : bounds_(bounds), context_factory_(context_factory), window_(nil) { 109} 110 111TestCompositorHostMac::~TestCompositorHostMac() { 112 // Release reference to |compositor_|. Important because the |compositor_| 113 // holds |this| as its delegate, so that reference must be removed here. 114 [[window_ contentView] setCompositor:NULL]; 115 [window_ setContentView:nil]; 116 117 [window_ orderOut:nil]; 118 [window_ close]; 119} 120 121void TestCompositorHostMac::Show() { 122 DCHECK(!window_); 123 window_ = [[NSWindow alloc] 124 initWithContentRect:NSMakeRect(bounds_.x(), 125 bounds_.y(), 126 bounds_.width(), 127 bounds_.height()) 128 styleMask:NSBorderlessWindowMask 129 backing:NSBackingStoreBuffered 130 defer:NO]; 131 base::scoped_nsobject<AcceleratedTestView> view( 132 [[AcceleratedTestView alloc] init]); 133 compositor_.reset(new ui::Compositor(view, context_factory_)); 134 compositor_->SetScaleAndSize(1.0f, bounds_.size()); 135 [view setCompositor:compositor_.get()]; 136 [window_ setContentView:view]; 137 [window_ orderFront:nil]; 138} 139 140ui::Compositor* TestCompositorHostMac::GetCompositor() { 141 return compositor_.get(); 142} 143 144// static 145TestCompositorHost* TestCompositorHost::Create( 146 const gfx::Rect& bounds, 147 ui::ContextFactory* context_factory) { 148 return new TestCompositorHostMac(bounds, context_factory); 149} 150 151} // namespace ui 152