test_compositor_host_mac.mm revision 5821806d5e7f356e8fa4b058a389a808ea183019
15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/compositor/test/test_compositor_host.h"
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#import <AppKit/NSApplication.h>
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#import <AppKit/NSOpenGL.h>
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#import <AppKit/NSView.h>
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#import <AppKit/NSWindow.h>
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#import <Foundation/NSAutoreleasePool.h>
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/compiler_specific.h"
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/scoped_nsobject.h"
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/scoped_ptr.h"
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/compositor/compositor.h"
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/gfx/rect.h"
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// AcceleratedTestView provides an NSView class that delegates drawing to a
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// ui::Compositor delegate, setting up the NSOpenGLContext as required.
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)@interface AcceleratedTestView : NSView {
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ui::Compositor* compositor_;
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Designated initializer.
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)-(id)init;
265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)-(void)setCompositor:(ui::Compositor*)compositor;
275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)@end
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)@implementation AcceleratedTestView
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)-(id)init {
315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // The frame will be resized when reparented into the window's view hierarchy.
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  self = [super initWithFrame:NSZeroRect];
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return self;
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)-(void)setCompositor:(ui::Compositor*)compositor {
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  compositor_ = compositor;
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)- (void)drawRect:(NSRect)rect {
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(compositor_) << "Drawing with no compositor set.";
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  compositor_->Draw(false);
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)@end
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace ui {
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Tests that use Objective-C memory semantics need to have a top-level
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// NSAutoreleasePool set up and initialized prior to execution and drained upon
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// exit.  The tests will leak otherwise.
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class FoundationHost {
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protected:
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  FoundationHost() {
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    pool_ = [[NSAutoreleasePool alloc] init];
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual ~FoundationHost() {
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    [pool_ drain];
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NSAutoreleasePool* pool_;
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(FoundationHost);
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Tests that use the AppKit framework need to have the NSApplication
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// initialized prior to doing anything with display objects such as windows,
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// views, or controls.
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class AppKitHost : public FoundationHost {
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protected:
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  AppKitHost() {
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    [NSApplication sharedApplication];
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual ~AppKitHost() {
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(AppKitHost);
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// TestCompositorHostMac provides a window surface and a coordinated compositor
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// for use in the compositor unit tests.
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class TestCompositorHostMac : public TestCompositorHost,
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                              public CompositorDelegate,
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                              public AppKitHost {
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  TestCompositorHostMac(const gfx::Rect& bounds);
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual ~TestCompositorHostMac();
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // TestCompositorHost:
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void Show() OVERRIDE;
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual ui::Compositor* GetCompositor() OVERRIDE;
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // CompositorDelegate:
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void ScheduleDraw() OVERRIDE;
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  gfx::Rect bounds_;
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_ptr<ui::Compositor> compositor_;
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Owned.  Released when window is closed.
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  NSWindow* window_;
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(TestCompositorHostMac);
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TestCompositorHostMac::TestCompositorHostMac(const gfx::Rect& bounds)
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    : bounds_(bounds), window_(nil) {
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TestCompositorHostMac::~TestCompositorHostMac() {
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Release reference to |compositor_|.  Important because the |compositor_|
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // holds |this| as its delegate, so that reference must be removed here.
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  [[window_ contentView] setCompositor:NULL];
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  [window_ setContentView:nil];
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  [window_ orderOut:nil];
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  [window_ close];
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void TestCompositorHostMac::Show() {
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  DCHECK(!window_);
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  window_ = [[NSWindow alloc]
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                initWithContentRect:NSMakeRect(bounds_.x(),
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                               bounds_.y(),
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                               bounds_.width(),
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                               bounds_.height())
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                          styleMask:NSBorderlessWindowMask
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                            backing:NSBackingStoreBuffered
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                              defer:NO];
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_nsobject<AcceleratedTestView> view([[AcceleratedTestView alloc] init]);
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  compositor_.reset(new ui::Compositor(this, view, bounds_.size()));
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  [view setCompositor:compositor_.get()];
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  [window_ setContentView:view];
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  [window_ orderFront:nil];
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ui::Compositor* TestCompositorHostMac::GetCompositor() {
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return compositor_.get();
138eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch}
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void TestCompositorHostMac::ScheduleDraw() {
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (!compositor_.get())
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return;
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Force display now.
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  [window_ display];
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TestCompositorHost* TestCompositorHost::Create(const gfx::Rect& bounds) {
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return new TestCompositorHostMac(bounds);
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}  // namespace ui
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)