Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(168)

Side by Side Diff: content/common/gpu/media/rendering_helper_mac.mm

Issue 10388108: Implement media::VideoDecodeAccelerator on Mac (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: a Created 8 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
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 "content/common/gpu/media/rendering_helper.h"
6
7 #import <Cocoa/Cocoa.h>
8 #import <OpenGL/gl.h>
9 #import <OpenGL/CGLMacro.h>
10
11 #include "base/mac/scoped_nsautorelease_pool.h"
12 #include "base/memory/scoped_nsobject.h"
13 #include "base/message_loop.h"
14 #include "base/synchronization/waitable_event.h"
15
16 namespace {
17
18 // Gets the pixel format to be used by the OpenGL view.
19 scoped_nsobject<NSOpenGLPixelFormat> GetPixelFormat() {
20 NSOpenGLPixelFormatAttribute attributes[] = {
21 NSOpenGLPFAWindow,
22 NSOpenGLPFADoubleBuffer,
23 NSOpenGLPFAAccelerated,
24 NSOpenGLPFANoRecovery,
25 NSOpenGLPFAColorSize, (NSOpenGLPixelFormatAttribute)32,
26 NSOpenGLPFAAlphaSize, (NSOpenGLPixelFormatAttribute)8,
27 NSOpenGLPFADepthSize, (NSOpenGLPixelFormatAttribute)24,
28 (NSOpenGLPixelFormatAttribute)0
29 };
30 return scoped_nsobject<NSOpenGLPixelFormat>(
31 [[NSOpenGLPixelFormat alloc] initWithAttributes:attributes]);
32 }
33
34 // Gets the CGLContext from the given OpenGL view.
35 CGLContextObj GetCGLContext(NSOpenGLView* gl_view) {
36 return static_cast<CGLContextObj>([[gl_view openGLContext] CGLContextObj]);
37 }
38
39 // Sets up a view port for the OpenGL view.
40 void SetupGLViewPort(NSOpenGLView* gl_view, int width, int height) {
41 CGLContextObj cgl_ctx = GetCGLContext(gl_view);
42 glViewport(0, 0, width, height);
43 glClearColor(1.0, 0.0, 0.0, 0.0);
44 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
45 [[gl_view openGLContext] flushBuffer];
46 CHECK_EQ(GL_NO_ERROR, static_cast<int>(glGetError()));
47 }
48
49 // Draw the given texture to the OpenGL view.
50 void DrawTexture(NSOpenGLView* gl_view, GLuint texture_id) {
51 CGLContextObj cgl_ctx = GetCGLContext(gl_view);
52 [gl_view lockFocus];
53
54 GLfloat width = [gl_view bounds].size.width;
55 GLfloat height = [gl_view bounds].size.height;
56
57 glEnable(GL_TEXTURE_RECTANGLE_ARB);
58 glBindTexture(GL_TEXTURE_RECTANGLE_ARB, texture_id);
59 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
60
61 glBegin(GL_QUADS);
62 glTexCoord2f(0.0, height);
63 glVertex3f(-1.0, -1.0, 0.0);
64 glTexCoord2f(width, height);
65 glVertex3f(1.0, -1.0, 0.0);
66 glTexCoord2f(width, 0.0);
67 glVertex3f(1.0, 1.0, 0.0);
68 glTexCoord2f(0.0, 0.0);
69 glVertex3f(-1.0, 1.0, 0.0);
70 glEnd();
71
72 glBindTexture(GL_TEXTURE_RECTANGLE_ARB, 0);
73 glDisable(GL_TEXTURE_RECTANGLE_ARB);
74
75 [[gl_view openGLContext] flushBuffer];
76 [gl_view unlockFocus];
77 CHECK_EQ(GL_NO_ERROR, static_cast<int>(glGetError()));
78 }
79
80 } // namespace
81
82 namespace video_test_util {
83
84 class RenderingHelperMac : public RenderingHelper {
85 public:
86 RenderingHelperMac();
87 virtual ~RenderingHelperMac();
88
89 // Implement RenderingHelper.
90 virtual void Initialize(bool suppress_swap_to_display,
91 int num_windows,
92 int width,
93 int height,
94 base::WaitableEvent* done) OVERRIDE;
95 virtual void UnInitialize(base::WaitableEvent* done) OVERRIDE;
96 virtual void CreateTexture(int window_id,
97 GLuint* texture_id,
98 base::WaitableEvent* done) OVERRIDE;
99 virtual void RenderTexture(GLuint texture_id) OVERRIDE;
100 virtual void DeleteTexture(GLuint texture_id) OVERRIDE;
101 virtual void* GetGLContext() OVERRIDE;
102 virtual void* GetGLDisplay() OVERRIDE;
103 virtual MessageLoop* GetMessageLoop() OVERRIDE;
104
105 private:
106 MessageLoop* message_loop_;
107 int width_;
108 int height_;
109 scoped_nsobject<NSWindow> window_;
110 scoped_nsobject<NSOpenGLView> gl_view_;
111 base::mac::ScopedNSAutoreleasePool pool_;
112 };
113
114 // static
115 RenderingHelper* RenderingHelper::Create() {
116 return new RenderingHelperMac;
117 }
118
119 // static
120 void RenderingHelper::InitializePlatform() {
121 // Initialize the Cocoa framework.
122 base::mac::ScopedNSAutoreleasePool pool_;
123 [NSApplication sharedApplication];
Robert Sesek 2012/05/15 16:04:49 What if this is called before +[CrApplication shar
sail 2012/05/15 23:53:31 Hm... I don't understand how this works. Can you p
124 }
125
126 RenderingHelperMac::RenderingHelperMac()
127 : message_loop_(NULL),
128 width_(0),
129 height_(0) {
130 }
131
132 RenderingHelperMac::~RenderingHelperMac() {
133 CHECK_EQ(width_, 0) << "Must call UnInitialize before dtor.";
134 }
135
136 void RenderingHelperMac::Initialize(bool suppress_swap_to_display,
137 int num_windows,
138 int width,
139 int height,
140 base::WaitableEvent* done) {
141 // Use width_ != 0 as a proxy for the class having already been
142 // Initialize()'d, and UnInitialize() before continuing.
143 if (width_) {
144 base::WaitableEvent done2(false, false);
145 UnInitialize(&done2);
146 done2.Wait();
147 }
148
149 // A separate window is created for each decoder. Since the Mac API
150 // only supports a single instance only one window should be created.
151 CHECK(num_windows == 1);
Robert Sesek 2012/05/15 16:04:49 CHECK_EQ
sail 2012/05/15 23:53:31 Done.
152
153 // Suppress swap is only used when multiple NALUs are sent to a single
154 // Decode() call. This is also not support by the Mac API.
155 CHECK(!suppress_swap_to_display);
156
157 width_ = width;
158 height_ = height;
159 message_loop_ = MessageLoop::current();
160
161 // Create a window to host the OpenGL contents.
162 NSRect rect = NSMakeRect(0, 0, width_, height_);
163 window_.reset([[NSWindow alloc]
164 initWithContentRect:rect
165 styleMask:NSTitledWindowMask
166 backing:NSBackingStoreBuffered
167 defer:NO]);
168 [window_ center];
169 [window_ makeKeyAndOrderFront:nil];
170
171 // Create an OpenGL view.
172 scoped_nsobject<NSOpenGLPixelFormat> pixel_format(GetPixelFormat());
173 gl_view_.reset([[NSOpenGLView alloc] initWithFrame:rect
174 pixelFormat:pixel_format]);
175 [[window_ contentView] addSubview:gl_view_];
176 SetupGLViewPort(gl_view_, width_, height_);
177
178 done->Signal();
Robert Sesek 2012/05/15 16:04:49 What thread is going to be waiting on this?
sail 2012/05/15 23:53:31 The main thread will be waiting for this. See: htt
179 }
180
181 void RenderingHelperMac::UnInitialize(base::WaitableEvent* done) {
182 CHECK_EQ(MessageLoop::current(), message_loop_);
183 width_ = 0;
184 height_ = 0;
185 message_loop_ = NULL;
186 [window_ close];
187 window_.reset();
188 gl_view_.reset();
189 done->Signal();
190 }
191
192 void RenderingHelperMac::CreateTexture(int window_id,
193 GLuint* texture_id,
194 base::WaitableEvent* done) {
195 CHECK_EQ(MessageLoop::current(), message_loop_);
196 CGLContextObj cgl_ctx = GetCGLContext(gl_view_);
197 glGenTextures(1, texture_id);
198 CHECK_EQ(GL_NO_ERROR, static_cast<int>(glGetError()));
199 done->Signal();
200 }
201
202 void RenderingHelperMac::RenderTexture(GLuint texture_id) {
203 CHECK_EQ(MessageLoop::current(), message_loop_);
204 DrawTexture(gl_view_, texture_id);
205 }
206
207 void RenderingHelperMac::DeleteTexture(GLuint texture_id) {
208 CHECK_EQ(MessageLoop::current(), message_loop_);
209 CGLContextObj cgl_ctx = GetCGLContext(gl_view_);
210 glDeleteTextures(1, &texture_id);
211 CHECK_EQ(GL_NO_ERROR, static_cast<int>(glGetError()));
212 }
213
214 void* RenderingHelperMac::GetGLContext() {
215 return GetCGLContext(gl_view_);
216 }
217
218 void* RenderingHelperMac::GetGLDisplay() {
219 return NULL;
220 }
221
222 MessageLoop* RenderingHelperMac::GetMessageLoop() {
223 return message_loop_;
224 }
225
226 } // namespace video_test_util
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698