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" 14eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "base/mac/scoped_nsobject.h" 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/scoped_ptr.h" 161320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "base/thread_task_runner_handle.h" 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/compositor/compositor.h" 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "ui/gfx/rect.h" 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// AcceleratedTestView provides an NSView class that delegates drawing to a 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// ui::Compositor delegate, setting up the NSOpenGLContext as required. 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)@interface AcceleratedTestView : NSView { 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ui::Compositor* compositor_; 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Designated initializer. 265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)-(id)init; 275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)-(void)setCompositor:(ui::Compositor*)compositor; 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)@end 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)@implementation AcceleratedTestView 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)-(id)init { 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // The frame will be resized when reparented into the window's view hierarchy. 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) self = [super initWithFrame:NSZeroRect]; 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return self; 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)-(void)setCompositor:(ui::Compositor*)compositor { 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) compositor_ = compositor; 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)- (void)drawRect:(NSRect)rect { 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(compositor_) << "Drawing with no compositor set."; 43c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles) compositor_->Draw(); 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)@end 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace ui { 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Tests that use Objective-C memory semantics need to have a top-level 505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// NSAutoreleasePool set up and initialized prior to execution and drained upon 515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// exit. The tests will leak otherwise. 525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class FoundationHost { 535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protected: 545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) FoundationHost() { 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) pool_ = [[NSAutoreleasePool alloc] init]; 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual ~FoundationHost() { 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) [pool_ drain]; 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NSAutoreleasePool* pool_; 635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(FoundationHost); 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Tests that use the AppKit framework need to have the NSApplication 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// initialized prior to doing anything with display objects such as windows, 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// views, or controls. 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class AppKitHost : public FoundationHost { 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protected: 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) AppKitHost() { 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) [NSApplication sharedApplication]; 735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual ~AppKitHost() { 755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(AppKitHost); 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// TestCompositorHostMac provides a window surface and a coordinated compositor 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// for use in the compositor unit tests. 825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)class TestCompositorHostMac : public TestCompositorHost, 835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public AppKitHost { 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 85cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) TestCompositorHostMac(const gfx::Rect& bounds, 86cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) ui::ContextFactory* context_factory); 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual ~TestCompositorHostMac(); 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private: 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // TestCompositorHost: 915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void Show() OVERRIDE; 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual ui::Compositor* GetCompositor() OVERRIDE; 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) gfx::Rect bounds_; 95cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 96cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) ui::ContextFactory* context_factory_; 97cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) 985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<ui::Compositor> compositor_; 995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Owned. Released when window is closed. 1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NSWindow* window_; 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(TestCompositorHostMac); 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 106cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)TestCompositorHostMac::TestCompositorHostMac( 107cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) const gfx::Rect& bounds, 108cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) ui::ContextFactory* context_factory) 109cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) : bounds_(bounds), context_factory_(context_factory), window_(nil) { 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TestCompositorHostMac::~TestCompositorHostMac() { 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Release reference to |compositor_|. Important because the |compositor_| 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // holds |this| as its delegate, so that reference must be removed here. 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) [[window_ contentView] setCompositor:NULL]; 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) [window_ setContentView:nil]; 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) [window_ orderOut:nil]; 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) [window_ close]; 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void TestCompositorHostMac::Show() { 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(!window_); 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) window_ = [[NSWindow alloc] 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) initWithContentRect:NSMakeRect(bounds_.x(), 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bounds_.y(), 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bounds_.width(), 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bounds_.height()) 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) styleMask:NSBorderlessWindowMask 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) backing:NSBackingStoreBuffered 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) defer:NO]; 132eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch base::scoped_nsobject<AcceleratedTestView> view( 133eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch [[AcceleratedTestView alloc] init]); 1345f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) compositor_.reset(new ui::Compositor(view, 1355f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) context_factory_, 1361320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci base::ThreadTaskRunnerHandle::Get())); 1375d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) compositor_->SetScaleAndSize(1.0f, bounds_.size()); 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) [view setCompositor:compositor_.get()]; 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) [window_ setContentView:view]; 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) [window_ orderFront:nil]; 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ui::Compositor* TestCompositorHostMac::GetCompositor() { 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return compositor_.get(); 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static 148cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)TestCompositorHost* TestCompositorHost::Create( 149cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) const gfx::Rect& bounds, 150cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) ui::ContextFactory* context_factory) { 151cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles) return new TestCompositorHostMac(bounds, context_factory); 1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace ui 155