1/*
2 *  Copyright (c) 2013 The WebRTC project authors. All Rights Reserved.
3 *
4 *  Use of this source code is governed by a BSD-style license
5 *  that can be found in the LICENSE file in the root of the source
6 *  tree. An additional intellectual property rights grant can be found
7 *  in the file PATENTS.  All contributing project authors may
8 *  be found in the AUTHORS file in the root of the source tree.
9 */
10
11#include "webrtc/test/mac/video_renderer_mac.h"
12
13#import <Cocoa/Cocoa.h>
14
15// Creates a Cocoa Window with an OpenGL context, used together with an OpenGL
16// renderer.
17@interface CocoaWindow : NSObject {
18 @private
19  NSWindow *window_;
20  NSOpenGLContext *context_;
21  NSString *title_;
22  int width_;
23  int height_;
24}
25
26- (id)initWithTitle:(NSString *)title width:(int)width height:(int)height;
27// 'createWindow' must be called on the main thread.
28- (void)createWindow:(NSObject *)ignored;
29- (void)makeCurrentContext;
30
31@end
32
33@implementation CocoaWindow
34  static NSInteger nextXOrigin_;
35  static NSInteger nextYOrigin_;
36
37- (id)initWithTitle:(NSString *)title width:(int)width height:(int)height {
38  if (self = [super init]) {
39    title_ = title;
40    width_ = width;
41    height_ = height;
42  }
43  return self;
44}
45
46- (void)dealloc {
47  [window_ release];
48  [super dealloc];
49}
50
51- (void)createWindow:(NSObject *)ignored {
52  NSInteger xOrigin = nextXOrigin_;
53  NSRect screenFrame = [[NSScreen mainScreen] frame];
54  if (nextXOrigin_ + width_ < screenFrame.size.width) {
55    nextXOrigin_ += width_;
56  } else {
57    xOrigin = 0;
58    nextXOrigin_ = 0;
59    nextYOrigin_ += height_;
60  }
61  if (nextYOrigin_ + height_ > screenFrame.size.height) {
62    xOrigin = 0;
63    nextXOrigin_ = 0;
64    nextYOrigin_ = 0;
65  }
66  NSInteger yOrigin = nextYOrigin_;
67  NSRect windowFrame = NSMakeRect(xOrigin, yOrigin, width_, height_);
68  window_ = [[NSWindow alloc] initWithContentRect:windowFrame
69                                        styleMask:NSTitledWindowMask
70                                          backing:NSBackingStoreBuffered
71                                            defer:NO];
72
73  NSRect viewFrame = NSMakeRect(0, 0, width_, height_);
74  NSOpenGLView *view = [[[NSOpenGLView alloc] initWithFrame:viewFrame
75                                                pixelFormat:nil] autorelease];
76  context_ = [view openGLContext];
77
78  [[window_ contentView] addSubview:view];
79  [window_ setTitle:title_];
80  [window_ makeKeyAndOrderFront:NSApp];
81}
82
83- (void)makeCurrentContext {
84  [context_ makeCurrentContext];
85}
86
87@end
88
89namespace webrtc {
90namespace test {
91
92VideoRenderer* VideoRenderer::CreatePlatformRenderer(const char* window_title,
93                                                     size_t width,
94                                                     size_t height) {
95  MacRenderer* renderer = new MacRenderer();
96  if (!renderer->Init(window_title, width, height)) {
97    delete renderer;
98    return NULL;
99  }
100  return renderer;
101}
102
103MacRenderer::MacRenderer()
104    : window_(NULL) {}
105
106MacRenderer::~MacRenderer() {
107  GlRenderer::Destroy();
108  [window_ release];
109}
110
111bool MacRenderer::Init(const char* window_title, int width, int height) {
112  window_ = [[CocoaWindow alloc]
113      initWithTitle:[NSString stringWithUTF8String:window_title]
114                                             width:width
115                                            height:height];
116  if (!window_)
117    return false;
118  [window_ performSelectorOnMainThread:@selector(createWindow:)
119                            withObject:nil
120                         waitUntilDone:YES];
121
122  [window_ makeCurrentContext];
123  GlRenderer::Init();
124  GlRenderer::ResizeViewport(width, height);
125  return true;
126}
127
128void MacRenderer::RenderFrame(const I420VideoFrame& frame, int /*delta*/) {
129  [window_ makeCurrentContext];
130  GlRenderer::RenderFrame(frame, 0);
131}
132
133}  // test
134}  // webrtc
135