1b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org/*
2b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org *  Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
3b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org *
4b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org *  Use of this source code is governed by a BSD-style license
5b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org *  that can be found in the LICENSE file in the root of the source
6b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org *  tree. An additional intellectual property rights grant can be found
7b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org *  in the file PATENTS.  All contributing project authors may
8b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org *  be found in the AUTHORS file in the root of the source tree.
9b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org */
10b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
119965e3a3af371325c85c3f740dd9b3547f67a4eapbos@webrtc.org#include "webrtc/engine_configurations.h"
12b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org#if defined(COCOA_RENDERING)
13b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
149965e3a3af371325c85c3f740dd9b3547f67a4eapbos@webrtc.org#include "webrtc/common_video/libyuv/include/webrtc_libyuv.h"
1587ec04aa08539233a29819d1c36ba8fc2b3d16e6andresp@webrtc.org#include "webrtc/modules/video_render/mac/video_render_nsopengl.h"
1687ec04aa08539233a29819d1c36ba8fc2b3d16e6andresp@webrtc.org#include "webrtc/system_wrappers/interface/critical_section_wrapper.h"
1787ec04aa08539233a29819d1c36ba8fc2b3d16e6andresp@webrtc.org#include "webrtc/system_wrappers/interface/event_wrapper.h"
1887ec04aa08539233a29819d1c36ba8fc2b3d16e6andresp@webrtc.org#include "webrtc/system_wrappers/interface/thread_wrapper.h"
1987ec04aa08539233a29819d1c36ba8fc2b3d16e6andresp@webrtc.org#include "webrtc/system_wrappers/interface/trace.h"
20b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
21b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgnamespace webrtc {
22b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
23b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgVideoChannelNSOpenGL::VideoChannelNSOpenGL(NSOpenGLContext *nsglContext, int iId, VideoRenderNSOpenGL* owner) :
24b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org_nsglContext( nsglContext),
25b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org_id( iId),
26b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org_owner( owner),
27b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org_width( 0),
28b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org_height( 0),
29b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org_startWidth( 0.0f),
30b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org_startHeight( 0.0f),
31b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org_stopWidth( 0.0f),
32b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org_stopHeight( 0.0f),
33b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org_stretchedWidth( 0),
34b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org_stretchedHeight( 0),
35b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org_oldStretchedHeight( 0),
36b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org_oldStretchedWidth( 0),
37b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org_buffer( 0),
38b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org_bufferSize( 0),
39b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org_incommingBufferSize( 0),
40b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org_bufferIsUpdated( false),
41b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org_numberOfStreams( 0),
42b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org_pixelFormat( GL_RGBA),
43b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org_pixelDataType( GL_UNSIGNED_INT_8_8_8_8),
44b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org_texture( 0)
45b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{
46b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
47b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
48b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
49b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgVideoChannelNSOpenGL::~VideoChannelNSOpenGL()
50b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{
51b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    if (_buffer)
52b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    {
53b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        delete [] _buffer;
54b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        _buffer = NULL;
55b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    }
56b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
57b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    if (_texture != 0)
58b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    {
59b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        [_nsglContext makeCurrentContext];
60b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        glDeleteTextures(1, (const GLuint*) &_texture);
61b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        _texture = 0;
62b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    }
63b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
64b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
65b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgint VideoChannelNSOpenGL::ChangeContext(NSOpenGLContext *nsglContext)
66b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{
67e9d2898e5f19b6d833444a5c5440ae9085cfd1f8sjlee@webrtc.org    _owner->LockAGLCntx();
68b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
69b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    _nsglContext = nsglContext;
70b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    [_nsglContext makeCurrentContext];
71b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
72b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    _owner->UnlockAGLCntx();
73b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    return 0;
74b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
75b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
76b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
77e1ca446434022ad0d05ebd5ed2feafb08ae940e3pbos@webrtc.orgint32_t VideoChannelNSOpenGL::GetChannelProperties(float& left, float& top,
78e1ca446434022ad0d05ebd5ed2feafb08ae940e3pbos@webrtc.org                                                   float& right, float& bottom)
79b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{
80b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
81b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    _owner->LockAGLCntx();
82b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
83b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    left = _startWidth;
84b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    top = _startHeight;
85b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    right = _stopWidth;
86b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    bottom = _stopHeight;
87b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
88b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    _owner->UnlockAGLCntx();
89b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    return 0;
90b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
91b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
92e1ca446434022ad0d05ebd5ed2feafb08ae940e3pbos@webrtc.orgint32_t VideoChannelNSOpenGL::RenderFrame(
93e1ca446434022ad0d05ebd5ed2feafb08ae940e3pbos@webrtc.org  const uint32_t /*streamId*/, I420VideoFrame& videoFrame) {
94b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
95b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  _owner->LockAGLCntx();
96b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
973bbed74cdcf1f27ce82104ce645ec0dcdd36902dmikhal@webrtc.org  if(_width != videoFrame.width() ||
983bbed74cdcf1f27ce82104ce645ec0dcdd36902dmikhal@webrtc.org     _height != videoFrame.height()) {
993bbed74cdcf1f27ce82104ce645ec0dcdd36902dmikhal@webrtc.org      if(FrameSizeChange(videoFrame.width(), videoFrame.height(), 1) == -1) {
100b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        _owner->UnlockAGLCntx();
101b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        return -1;
102b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org      }
103b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  }
104b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  int ret = DeliverFrame(videoFrame);
105b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
106b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  _owner->UnlockAGLCntx();
107b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  return ret;
108b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
109b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
110b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgint VideoChannelNSOpenGL::UpdateSize(int width, int height)
111b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{
112b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    _owner->LockAGLCntx();
113b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    _width = width;
114b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    _height = height;
115b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    _owner->UnlockAGLCntx();
116b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    return 0;
117b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
118b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
119b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgint VideoChannelNSOpenGL::UpdateStretchSize(int stretchHeight, int stretchWidth)
120b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{
121b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
122b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    _owner->LockAGLCntx();
123b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    _stretchedHeight = stretchHeight;
124b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    _stretchedWidth = stretchWidth;
125b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    _owner->UnlockAGLCntx();
126b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    return 0;
127b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
128b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
129b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgint VideoChannelNSOpenGL::FrameSizeChange(int width, int height, int numberOfStreams)
130b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{
131b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    //  We got a new frame size from VideoAPI, prepare the buffer
132b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
133b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    _owner->LockAGLCntx();
134b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
135b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    if (width == _width && _height == height)
136b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    {
137b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        // We already have a correct buffer size
138b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        _numberOfStreams = numberOfStreams;
139b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        _owner->UnlockAGLCntx();
140b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        return 0;
141b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    }
142b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
143b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    _width = width;
144b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    _height = height;
145b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
146b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    // Delete the old buffer, create a new one with correct size.
147b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    if (_buffer)
148b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    {
149b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        delete [] _buffer;
150b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        _bufferSize = 0;
151b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    }
152b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
153b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    _incommingBufferSize = CalcBufferSize(kI420, _width, _height);
154b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    _bufferSize = CalcBufferSize(kARGB, _width, _height);
155b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    _buffer = new unsigned char [_bufferSize];
156b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    memset(_buffer, 0, _bufferSize * sizeof(unsigned char));
157b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
158b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    [_nsglContext makeCurrentContext];
159b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
160b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    if(glIsTexture(_texture))
161b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    {
162b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        glDeleteTextures(1, (const GLuint*) &_texture);
163b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        _texture = 0;
164b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    }
165b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
166b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    // Create a new texture
167b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    glGenTextures(1, (GLuint *) &_texture);
168b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
169b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    GLenum glErr = glGetError();
170b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
171b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    if (glErr != GL_NO_ERROR)
172b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    {
173b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
174b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    }
175b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
176b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    glBindTexture(GL_TEXTURE_RECTANGLE_EXT, _texture);
177b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
178b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    GLint texSize;
179b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    glGetIntegerv(GL_MAX_TEXTURE_SIZE, &texSize);
180b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
181b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    if (texSize < _width || texSize < _height)
182b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    {
183b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        _owner->UnlockAGLCntx();
184b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        return -1;
185b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    }
186b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
187b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    // Set up th texture type and size
188b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    glTexImage2D(GL_TEXTURE_RECTANGLE_EXT, // target
189b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org            0, // level
190b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org            GL_RGBA, // internal format
191b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org            _width, // width
192b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org            _height, // height
193b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org            0, // border 0/1 = off/on
194b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org            _pixelFormat, // format, GL_RGBA
195b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org            _pixelDataType, // data type, GL_UNSIGNED_INT_8_8_8_8
196b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org            _buffer); // pixel data
197b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
198b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    glErr = glGetError();
199b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    if (glErr != GL_NO_ERROR)
200b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    {
201b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        _owner->UnlockAGLCntx();
202b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        return -1;
203b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    }
204b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
205b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    _owner->UnlockAGLCntx();
206b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    return 0;
207b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
208b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
2093bbed74cdcf1f27ce82104ce645ec0dcdd36902dmikhal@webrtc.orgint VideoChannelNSOpenGL::DeliverFrame(const I420VideoFrame& videoFrame) {
210b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
211b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  _owner->LockAGLCntx();
212b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
213b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  if (_texture == 0) {
214b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    _owner->UnlockAGLCntx();
215b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    return 0;
216b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  }
217b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
2183bbed74cdcf1f27ce82104ce645ec0dcdd36902dmikhal@webrtc.org  int length = CalcBufferSize(kI420, videoFrame.width(), videoFrame.height());
2193bbed74cdcf1f27ce82104ce645ec0dcdd36902dmikhal@webrtc.org  if (length != _incommingBufferSize) {
220b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    _owner->UnlockAGLCntx();
221b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    return -1;
222b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  }
223b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
2243bbed74cdcf1f27ce82104ce645ec0dcdd36902dmikhal@webrtc.org  // Using the I420VideoFrame for YV12: YV12 is YVU; I420 assumes
2253bbed74cdcf1f27ce82104ce645ec0dcdd36902dmikhal@webrtc.org  // YUV.
2263bbed74cdcf1f27ce82104ce645ec0dcdd36902dmikhal@webrtc.org  // TODO(mikhal) : Use appropriate functionality.
2273bbed74cdcf1f27ce82104ce645ec0dcdd36902dmikhal@webrtc.org  // TODO(wu): See if we are using glTexSubImage2D correctly.
2283bbed74cdcf1f27ce82104ce645ec0dcdd36902dmikhal@webrtc.org  int rgbRet = ConvertFromYV12(videoFrame, kBGRA, 0, _buffer);
229b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  if (rgbRet < 0) {
230b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    _owner->UnlockAGLCntx();
231b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    return -1;
232b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  }
233b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
234b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  [_nsglContext makeCurrentContext];
235b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
236b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  // Make sure this texture is the active one
237b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  glBindTexture(GL_TEXTURE_RECTANGLE_EXT, _texture);
238b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  GLenum glErr = glGetError();
239b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  if (glErr != GL_NO_ERROR) {
240b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    WEBRTC_TRACE(kTraceError, kTraceVideoRenderer, _id,
241b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    "ERROR %d while calling glBindTexture", glErr);
242b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    _owner->UnlockAGLCntx();
243b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    return -1;
244b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  }
245b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
246b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  glTexSubImage2D(GL_TEXTURE_RECTANGLE_EXT,
247b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                  0, // Level, not use
248b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                  0, // start point x, (low left of pic)
249b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                  0, // start point y,
250b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                  _width, // width
251b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                  _height, // height
252b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                  _pixelFormat, // pictue format for _buffer
253b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                  _pixelDataType, // data type of _buffer
254b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                  (const GLvoid*) _buffer); // the pixel data
255b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
256b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  glErr = glGetError();
257b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  if (glErr != GL_NO_ERROR) {
258b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    WEBRTC_TRACE(kTraceError, kTraceVideoRenderer, _id,
259b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    "ERROR %d while calling glTexSubImage2d", glErr);
260b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    _owner->UnlockAGLCntx();
261b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    return -1;
262b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  }
263b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
264b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  _bufferIsUpdated = true;
265b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
266b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  _owner->UnlockAGLCntx();
267b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org  return 0;
268b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
269b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
270b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgint VideoChannelNSOpenGL::RenderOffScreenBuffer()
271b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{
272b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
273b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    _owner->LockAGLCntx();
274b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
275b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    if (_texture == 0)
276b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    {
277b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        _owner->UnlockAGLCntx();
278b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        return 0;
279b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    }
280b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
281b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    //	if(_fullscreen)
282b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    //	{
283b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    // NSRect mainDisplayRect = [[NSScreen mainScreen] frame];
284b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    //		_width = mainDisplayRect.size.width;
285b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    //		_height = mainDisplayRect.size.height;
286b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    //		glViewport(0, 0, mainDisplayRect.size.width, mainDisplayRect.size.height);
287b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    //		float newX = mainDisplayRect.size.width/_width;
288b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    //		float newY = mainDisplayRect.size.height/_height;
289b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
290b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    // convert from 0.0 <= size <= 1.0 to
291b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    // open gl world -1.0 < size < 1.0
292b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    GLfloat xStart = 2.0f * _startWidth - 1.0f;
293b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    GLfloat xStop = 2.0f * _stopWidth - 1.0f;
294b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    GLfloat yStart = 1.0f - 2.0f * _stopHeight;
295b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    GLfloat yStop = 1.0f - 2.0f * _startHeight;
296b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
297b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    [_nsglContext makeCurrentContext];
298b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
299b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    glBindTexture(GL_TEXTURE_RECTANGLE_EXT, _texture);
300b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    _oldStretchedHeight = _stretchedHeight;
301b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    _oldStretchedWidth = _stretchedWidth;
302b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
303b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    glLoadIdentity();
304b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    glEnable(GL_TEXTURE_RECTANGLE_EXT);
305b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    glBegin(GL_POLYGON);
306b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    {
307b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        glTexCoord2f(0.0, 0.0); glVertex2f(xStart, yStop);
308b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        glTexCoord2f(_width, 0.0); glVertex2f(xStop, yStop);
309b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        glTexCoord2f(_width, _height); glVertex2f(xStop, yStart);
310b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        glTexCoord2f(0.0, _height); glVertex2f(xStart, yStart);
311b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    }
312b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    glEnd();
313b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
314b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    glDisable(GL_TEXTURE_RECTANGLE_EXT);
315b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
316b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    _bufferIsUpdated = false;
317b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
318b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    _owner->UnlockAGLCntx();
319b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    return 0;
320b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
321b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
322b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgint VideoChannelNSOpenGL::IsUpdated(bool& isUpdated)
323b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{
324b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    _owner->LockAGLCntx();
325b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
326b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    isUpdated = _bufferIsUpdated;
327b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
328b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    _owner->UnlockAGLCntx();
329b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    return 0;
330b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
331b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
332b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgint VideoChannelNSOpenGL::SetStreamSettings(int /*streamId*/, float startWidth, float startHeight, float stopWidth, float stopHeight)
333b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{
334b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    _owner->LockAGLCntx();
335b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
336b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    _startWidth = startWidth;
337b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    _stopWidth = stopWidth;
338b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    _startHeight = startHeight;
339b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    _stopHeight = stopHeight;
340b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
341b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    int oldWidth = _width;
342b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    int oldHeight = _height;
343b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    int oldNumberOfStreams = _numberOfStreams;
344b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
345b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    _width = 0;
346b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    _height = 0;
347b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
348b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    int retVal = FrameSizeChange(oldWidth, oldHeight, oldNumberOfStreams);
349b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
350b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    _owner->UnlockAGLCntx();
351b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    return retVal;
352b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
353b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
354b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgint VideoChannelNSOpenGL::SetStreamCropSettings(int /*streamId*/, float /*startWidth*/, float /*startHeight*/, float /*stopWidth*/, float /*stopHeight*/)
355b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{
356b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    return -1;
357b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
358b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
359b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org/*
360b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org *
361b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org *    VideoRenderNSOpenGL
362b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org *
363b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org */
364b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
365b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgVideoRenderNSOpenGL::VideoRenderNSOpenGL(CocoaRenderView *windowRef, bool fullScreen, int iId) :
366b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org_windowRef( (CocoaRenderView*)windowRef),
367b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org_fullScreen( fullScreen),
368b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org_id( iId),
369b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org_nsglContextCritSec( *CriticalSectionWrapper::CreateCriticalSection()),
370b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org_screenUpdateThread( 0),
371b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org_screenUpdateEvent( 0),
372b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org_nsglContext( 0),
373b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org_nsglFullScreenContext( 0),
374b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org_fullScreenWindow( nil),
375b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org_windowRect( ),
376b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org_windowWidth( 0),
377b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org_windowHeight( 0),
378b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org_nsglChannels( ),
379b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org_zOrderToChannel( ),
380b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org_threadID (0),
381b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org_renderingIsPaused (FALSE),
382b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org_windowRefSuperView(NULL),
383b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org_windowRefSuperViewFrame(NSMakeRect(0,0,0,0))
384b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{
385b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    _screenUpdateThread = ThreadWrapper::CreateThread(ScreenUpdateThreadProc, this, kRealtimePriority);
386b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    _screenUpdateEvent = EventWrapper::Create();
387b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
388b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
389b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgint VideoRenderNSOpenGL::ChangeWindow(CocoaRenderView* newWindowRef)
390b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{
391b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
392b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    LockAGLCntx();
393b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
394b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    _windowRef = newWindowRef;
395b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
396b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    if(CreateMixingContext() == -1)
397b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    {
398b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        UnlockAGLCntx();
399b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        return -1;
400b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    }
401b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
402b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    int error = 0;
403b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    std::map<int, VideoChannelNSOpenGL*>::iterator it = _nsglChannels.begin();
404b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    while (it!= _nsglChannels.end())
405b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    {
406b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        error |= (it->second)->ChangeContext(_nsglContext);
407b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        it++;
408b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    }
409b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    if(error != 0)
410b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    {
411b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        UnlockAGLCntx();
412b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        return -1;
413b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    }
414b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
415b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    UnlockAGLCntx();
416b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    return 0;
417b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
418b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
419b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org/* Check if the thread and event already exist.
420b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * If so then they will simply be restarted
421b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * If not then create them and continue
422b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org */
423e1ca446434022ad0d05ebd5ed2feafb08ae940e3pbos@webrtc.orgint32_t VideoRenderNSOpenGL::StartRender()
424b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{
425b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
426b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    LockAGLCntx();
427b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
428b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    const unsigned int MONITOR_FREQ = 60;
429b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    if(TRUE == _renderingIsPaused)
430b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    {
431b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        WEBRTC_TRACE(kTraceDebug, kTraceVideoRenderer, _id, "Restarting screenUpdateThread");
432b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
433b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        // we already have the thread. Most likely StopRender() was called and they were paused
434b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        if(FALSE == _screenUpdateThread->Start(_threadID) ||
435b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                FALSE == _screenUpdateEvent->StartTimer(true, 1000/MONITOR_FREQ))
436b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        {
437b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org            WEBRTC_TRACE(kTraceError, kTraceVideoRenderer, _id, "Failed to restart screenUpdateThread or screenUpdateEvent");
438b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org            UnlockAGLCntx();
439b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org            return -1;
440b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        }
441b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
442b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        UnlockAGLCntx();
443b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        return 0;
444b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    }
445b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
446b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
447b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    if (!_screenUpdateThread)
448b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    {
449b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        WEBRTC_TRACE(kTraceDebug, kTraceVideoRenderer, _id, "failed start screenUpdateThread");
450b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        UnlockAGLCntx();
451b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        return -1;
452b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    }
453b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
454b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
455b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    UnlockAGLCntx();
456b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    return 0;
457b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
458e1ca446434022ad0d05ebd5ed2feafb08ae940e3pbos@webrtc.orgint32_t VideoRenderNSOpenGL::StopRender()
459b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{
460b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
461b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    LockAGLCntx();
462b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
463b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    /* The code below is functional
464b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org     * but it pauses for several seconds
465b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org     */
466b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
467b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    // pause the update thread and the event timer
468b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    if(!_screenUpdateThread || !_screenUpdateEvent)
469b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    {
470b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        _renderingIsPaused = TRUE;
471b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
472b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        UnlockAGLCntx();
473b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        return 0;
474b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    }
475b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
476b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    if(FALSE == _screenUpdateThread->Stop() || FALSE == _screenUpdateEvent->StopTimer())
477b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    {
478b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        _renderingIsPaused = FALSE;
479b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
480b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        UnlockAGLCntx();
481b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        return -1;
482b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    }
483b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
484b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    _renderingIsPaused = TRUE;
485b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
486b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    UnlockAGLCntx();
487b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    return 0;
488b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
489b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
490b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgint VideoRenderNSOpenGL::configureNSOpenGLView()
491b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{
492b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    return 0;
493b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
494b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
495b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
496b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgint VideoRenderNSOpenGL::configureNSOpenGLEngine()
497b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{
498b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
499b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    LockAGLCntx();
500b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
501b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    // Disable not needed functionality to increase performance
502b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    glDisable(GL_DITHER);
503b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    glDisable(GL_ALPHA_TEST);
504b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    glDisable(GL_STENCIL_TEST);
505b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    glDisable(GL_FOG);
506b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    glDisable(GL_TEXTURE_2D);
507b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    glPixelZoom(1.0, 1.0);
508b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    glDisable(GL_BLEND);
509b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    glDisable(GL_DEPTH_TEST);
510b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    glDepthMask(GL_FALSE);
511b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    glDisable(GL_CULL_FACE);
512b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
513b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    // Set texture parameters
514b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    glTexParameterf(GL_TEXTURE_RECTANGLE_EXT, GL_TEXTURE_PRIORITY, 1.0);
515b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    glTexParameteri(GL_TEXTURE_RECTANGLE_EXT, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
516b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    glTexParameteri(GL_TEXTURE_RECTANGLE_EXT, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
517b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    glTexParameteri(GL_TEXTURE_RECTANGLE_EXT, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
518b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    glTexParameteri(GL_TEXTURE_RECTANGLE_EXT, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
519b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
520b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
521b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    glTexParameteri(GL_TEXTURE_RECTANGLE_EXT, GL_TEXTURE_STORAGE_HINT_APPLE, GL_STORAGE_SHARED_APPLE);
522b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
523b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    if (GetWindowRect(_windowRect) == -1)
524b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    {
525b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        UnlockAGLCntx();
526b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        return true;
527b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    }
528b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
529b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    if (_windowWidth != (_windowRect.right - _windowRect.left)
530b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org            || _windowHeight != (_windowRect.bottom - _windowRect.top))
531b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    {
532b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        _windowWidth = _windowRect.right - _windowRect.left;
533b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        _windowHeight = _windowRect.bottom - _windowRect.top;
534b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    }
535b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    glViewport(0, 0, _windowWidth, _windowHeight);
536b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
537b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    // Synchronize buffer swaps with vertical refresh rate
538b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    GLint swapInt = 1;
539b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    [_nsglContext setValues:&swapInt forParameter:NSOpenGLCPSwapInterval];
540b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
541b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    UnlockAGLCntx();
542b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    return 0;
543b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
544b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
545b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgint VideoRenderNSOpenGL::setRenderTargetWindow()
546b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{
547b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    LockAGLCntx();
548b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
549b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
550b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    GLuint attribs[] =
551b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    {
552b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        NSOpenGLPFAColorSize, 24,
553b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        NSOpenGLPFAAlphaSize, 8,
554b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        NSOpenGLPFADepthSize, 16,
555b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        NSOpenGLPFAAccelerated,
556b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        0
557b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    };
558b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
55909121dc0e019c0a3de9c5fa1f2d593d15b6a3f39niklas.enbom@webrtc.org    NSOpenGLPixelFormat* fmt = [[[NSOpenGLPixelFormat alloc] initWithAttributes:
56009121dc0e019c0a3de9c5fa1f2d593d15b6a3f39niklas.enbom@webrtc.org                          (NSOpenGLPixelFormatAttribute*) attribs] autorelease];
561b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
562b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    if(_windowRef)
563b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    {
564b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        [_windowRef initCocoaRenderView:fmt];
565b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    }
566b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    else
567b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    {
568b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        UnlockAGLCntx();
569b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        return -1;
570b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    }
571b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
572b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    _nsglContext = [_windowRef nsOpenGLContext];
573b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    [_nsglContext makeCurrentContext];
574b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
575b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
576b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    glClear(GL_COLOR_BUFFER_BIT);
577b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
578b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
579b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    DisplayBuffers();
580b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
581b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    UnlockAGLCntx();
582b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    return 0;
583b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
584b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
585b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgint VideoRenderNSOpenGL::setRenderTargetFullScreen()
586b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{
587b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    LockAGLCntx();
588b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
589b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
590b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    GLuint attribs[] =
591b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    {
592b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        NSOpenGLPFAColorSize, 24,
593b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        NSOpenGLPFAAlphaSize, 8,
594b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        NSOpenGLPFADepthSize, 16,
595b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        NSOpenGLPFAAccelerated,
596b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        0
597b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    };
598b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
59909121dc0e019c0a3de9c5fa1f2d593d15b6a3f39niklas.enbom@webrtc.org    NSOpenGLPixelFormat* fmt = [[[NSOpenGLPixelFormat alloc] initWithAttributes:
60009121dc0e019c0a3de9c5fa1f2d593d15b6a3f39niklas.enbom@webrtc.org                          (NSOpenGLPixelFormatAttribute*) attribs] autorelease];
601b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
602b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    // Store original superview and frame for use when exiting full screens
603b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    _windowRefSuperViewFrame = [_windowRef frame];
604b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    _windowRefSuperView = [_windowRef superview];
605b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
606b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
607b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    // create new fullscreen window
608b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    NSRect screenRect = [[NSScreen mainScreen]frame];
609b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    [_windowRef setFrame:screenRect];
610b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    [_windowRef setBounds:screenRect];
611b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
612b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
613b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    _fullScreenWindow = [[CocoaFullScreenWindow alloc]init];
614b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    [_fullScreenWindow grabFullScreen];
615b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    [[[_fullScreenWindow window] contentView] addSubview:_windowRef];
616b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
617b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    if(_windowRef)
618b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    {
619b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        [_windowRef initCocoaRenderViewFullScreen:fmt];
620b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    }
621b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    else
622b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    {
623b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        UnlockAGLCntx();
624b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        return -1;
625b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    }
626b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
627b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    _nsglContext = [_windowRef nsOpenGLContext];
628b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    [_nsglContext makeCurrentContext];
629b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
630b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
631b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    glClear(GL_COLOR_BUFFER_BIT);
632b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
633b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    DisplayBuffers();
634b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
635b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    UnlockAGLCntx();
636b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    return 0;
637b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
638b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
639b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgVideoRenderNSOpenGL::~VideoRenderNSOpenGL()
640b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{
641b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
642b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    if(_fullScreen)
643b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    {
644b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        if(_fullScreenWindow)
645b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        {
646b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org            // Detach CocoaRenderView from full screen view back to
647b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org            // it's original parent.
648b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org            [_windowRef removeFromSuperview];
649b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org            if(_windowRefSuperView)
650b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org            {
651b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org              [_windowRefSuperView addSubview:_windowRef];
652b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org              [_windowRef setFrame:_windowRefSuperViewFrame];
653b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org            }
654b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
655b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org            WEBRTC_TRACE(kTraceDebug, kTraceVideoRenderer, 0, "%s:%d Attempting to release fullscreen window", __FUNCTION__, __LINE__);
656b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org            [_fullScreenWindow releaseFullScreen];
657b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
658b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        }
659b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    }
660b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
661b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    // Signal event to exit thread, then delete it
662b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    ThreadWrapper* tmpPtr = _screenUpdateThread;
663b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    _screenUpdateThread = NULL;
664b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
665b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    if (tmpPtr)
666b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    {
667b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        tmpPtr->SetNotAlive();
668b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        _screenUpdateEvent->Set();
669b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        _screenUpdateEvent->StopTimer();
670b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
671b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        if (tmpPtr->Stop())
672b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        {
673b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org            delete tmpPtr;
674b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        }
675b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        delete _screenUpdateEvent;
676b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        _screenUpdateEvent = NULL;
677b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    }
678b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
679b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    if (_nsglContext != 0)
680b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    {
681b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        [_nsglContext makeCurrentContext];
682b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        _nsglContext = nil;
683b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    }
684b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
685b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    // Delete all channels
686b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    std::map<int, VideoChannelNSOpenGL*>::iterator it = _nsglChannels.begin();
687b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    while (it!= _nsglChannels.end())
688b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    {
689b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        delete it->second;
690b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        _nsglChannels.erase(it);
691b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        it = _nsglChannels.begin();
692b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    }
693b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    _nsglChannels.clear();
694b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
695b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    // Clean the zOrder map
696b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    std::multimap<int, int>::iterator zIt = _zOrderToChannel.begin();
697b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    while(zIt != _zOrderToChannel.end())
698b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    {
699b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        _zOrderToChannel.erase(zIt);
700b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        zIt = _zOrderToChannel.begin();
701b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    }
702b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    _zOrderToChannel.clear();
703b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
704b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
705b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
706b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org/* static */
707b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgint VideoRenderNSOpenGL::GetOpenGLVersion(int& /*nsglMajor*/, int& /*nsglMinor*/)
708b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{
709b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    return -1;
710b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
711b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
712b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgint VideoRenderNSOpenGL::Init()
713b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{
714b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
715b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    LockAGLCntx();
716b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    if (!_screenUpdateThread)
717b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    {
718b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        UnlockAGLCntx();
719b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        return -1;
720b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    }
721b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
722b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    _screenUpdateThread->Start(_threadID);
723b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
724b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    // Start the event triggering the render process
725b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    unsigned int monitorFreq = 60;
726b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    _screenUpdateEvent->StartTimer(true, 1000/monitorFreq);
727b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
728b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    if (CreateMixingContext() == -1)
729b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    {
730b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        UnlockAGLCntx();
731b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        return -1;
732b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    }
733b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
734b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    UnlockAGLCntx();
735b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    return 0;
736b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
737b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
738b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgVideoChannelNSOpenGL* VideoRenderNSOpenGL::CreateNSGLChannel(int channel, int zOrder, float startWidth, float startHeight, float stopWidth, float stopHeight)
739b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{
740b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    CriticalSectionScoped cs(&_nsglContextCritSec);
741b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
742b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    if (HasChannel(channel))
743b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    {
744b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        return NULL;
745b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    }
746b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
747b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    if (_zOrderToChannel.find(zOrder) != _zOrderToChannel.end())
748b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    {
749b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
750b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    }
751b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
752b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    VideoChannelNSOpenGL* newAGLChannel = new VideoChannelNSOpenGL(_nsglContext, _id, this);
753b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    if (newAGLChannel->SetStreamSettings(0, startWidth, startHeight, stopWidth, stopHeight) == -1)
754b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    {
755b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        if (newAGLChannel)
756b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        {
757b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org            delete newAGLChannel;
758b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org            newAGLChannel = NULL;
759b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        }
760b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
761b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        return NULL;
762b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    }
763b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
764b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    _nsglChannels[channel] = newAGLChannel;
765b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    _zOrderToChannel.insert(std::pair<int, int>(zOrder, channel));
766b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
767b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    WEBRTC_TRACE(kTraceInfo, kTraceVideoRenderer, _id, "%s successfully created NSGL channel number %d", __FUNCTION__, channel);
768b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
769b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    return newAGLChannel;
770b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
771b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
772b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgint VideoRenderNSOpenGL::DeleteAllNSGLChannels()
773b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{
774b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
775b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    CriticalSectionScoped cs(&_nsglContextCritSec);
776b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
777b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    std::map<int, VideoChannelNSOpenGL*>::iterator it;
778b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    it = _nsglChannels.begin();
779b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
780b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    while (it != _nsglChannels.end())
781b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    {
782b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        VideoChannelNSOpenGL* channel = it->second;
783b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        WEBRTC_TRACE(kTraceInfo, kTraceVideoRenderer, _id, "%s Deleting channel %d", __FUNCTION__, channel);
784b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        delete channel;
785b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        it++;
786b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    }
787b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    _nsglChannels.clear();
788b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    return 0;
789b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
790b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
791e1ca446434022ad0d05ebd5ed2feafb08ae940e3pbos@webrtc.orgint32_t VideoRenderNSOpenGL::DeleteNSGLChannel(const uint32_t channel)
792b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{
793b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
794b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    CriticalSectionScoped cs(&_nsglContextCritSec);
795b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
796b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    std::map<int, VideoChannelNSOpenGL*>::iterator it;
797b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    it = _nsglChannels.find(channel);
798b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    if (it != _nsglChannels.end())
799b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    {
800b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        delete it->second;
801b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        _nsglChannels.erase(it);
802b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    }
803b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    else
804b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    {
805b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        return -1;
806b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    }
807b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
808b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    std::multimap<int, int>::iterator zIt = _zOrderToChannel.begin();
809b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    while( zIt != _zOrderToChannel.end())
810b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    {
811b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        if (zIt->second == (int)channel)
812b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        {
813b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org            _zOrderToChannel.erase(zIt);
814b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org            break;
815b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        }
816b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        zIt++;
817b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    }
818b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
819b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    return 0;
820b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
821b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
822e1ca446434022ad0d05ebd5ed2feafb08ae940e3pbos@webrtc.orgint32_t VideoRenderNSOpenGL::GetChannelProperties(const uint16_t streamId,
823e1ca446434022ad0d05ebd5ed2feafb08ae940e3pbos@webrtc.org                                                  uint32_t& zOrder,
824e1ca446434022ad0d05ebd5ed2feafb08ae940e3pbos@webrtc.org                                                  float& left,
825e1ca446434022ad0d05ebd5ed2feafb08ae940e3pbos@webrtc.org                                                  float& top,
826e1ca446434022ad0d05ebd5ed2feafb08ae940e3pbos@webrtc.org                                                  float& right,
827e1ca446434022ad0d05ebd5ed2feafb08ae940e3pbos@webrtc.org                                                  float& bottom)
828b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{
829b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
830b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    CriticalSectionScoped cs(&_nsglContextCritSec);
831b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
832b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    bool channelFound = false;
833b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
834b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    // Loop through all channels until we find a match.
835b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    // From that, get zorder.
836b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    // From that, get T, L, R, B
837b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    for (std::multimap<int, int>::reverse_iterator rIt = _zOrderToChannel.rbegin();
838b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org            rIt != _zOrderToChannel.rend();
839b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org            rIt++)
840b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    {
841b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        if(streamId == rIt->second)
842b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        {
843b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org            channelFound = true;
844b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
845b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org            zOrder = rIt->second;
846b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
847b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org            std::map<int, VideoChannelNSOpenGL*>::iterator rIt = _nsglChannels.find(streamId);
848b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org            VideoChannelNSOpenGL* tempChannel = rIt->second;
849b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
850b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org            if(-1 == tempChannel->GetChannelProperties(left, top, right, bottom) )
851b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org            {
852b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                return -1;
853b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org            }
854b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org            break;
855b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        }
856b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    }
857b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
858b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    if(false == channelFound)
859b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    {
860b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
861b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        return -1;
862b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    }
863b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
864b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    return 0;
865b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
866b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
867b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgint VideoRenderNSOpenGL::StopThread()
868b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{
869b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
870b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    ThreadWrapper* tmpPtr = _screenUpdateThread;
871b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    WEBRTC_TRACE(kTraceInfo, kTraceVideoRenderer, _id, "%s Stopping thread ", __FUNCTION__, _screenUpdateThread);
872b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    _screenUpdateThread = NULL;
873b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
874b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    if (tmpPtr)
875b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    {
876b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        tmpPtr->SetNotAlive();
877b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        _screenUpdateEvent->Set();
878b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        if (tmpPtr->Stop())
879b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        {
880b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org            delete tmpPtr;
881b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        }
882b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    }
883b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
884b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    delete _screenUpdateEvent;
885b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    _screenUpdateEvent = NULL;
886b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
887b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    return 0;
888b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
889b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
890b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgbool VideoRenderNSOpenGL::IsFullScreen()
891b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{
892b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
893b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    CriticalSectionScoped cs(&_nsglContextCritSec);
894b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    return _fullScreen;
895b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
896b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
897b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgbool VideoRenderNSOpenGL::HasChannels()
898b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{
899b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    CriticalSectionScoped cs(&_nsglContextCritSec);
900b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
901b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    if (_nsglChannels.begin() != _nsglChannels.end())
902b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    {
903b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        return true;
904b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    }
905b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    return false;
906b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
907b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
908b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgbool VideoRenderNSOpenGL::HasChannel(int channel)
909b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{
910b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
911b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    CriticalSectionScoped cs(&_nsglContextCritSec);
912b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
913b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    std::map<int, VideoChannelNSOpenGL*>::iterator it = _nsglChannels.find(channel);
914b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
915b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    if (it != _nsglChannels.end())
916b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    {
917b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        return true;
918b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    }
919b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    return false;
920b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
921b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
922b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgint VideoRenderNSOpenGL::GetChannels(std::list<int>& channelList)
923b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{
924b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
925b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    CriticalSectionScoped cs(&_nsglContextCritSec);
926b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
927b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    std::map<int, VideoChannelNSOpenGL*>::iterator it = _nsglChannels.begin();
928b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
929b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    while (it != _nsglChannels.end())
930b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    {
931b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        channelList.push_back(it->first);
932b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        it++;
933b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    }
934b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
935b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    return 0;
936b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
937b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
938b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgVideoChannelNSOpenGL* VideoRenderNSOpenGL::ConfigureNSGLChannel(int channel, int zOrder, float startWidth, float startHeight, float stopWidth, float stopHeight)
939b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{
940b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
941b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    CriticalSectionScoped cs(&_nsglContextCritSec);
942b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
943b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    std::map<int, VideoChannelNSOpenGL*>::iterator it = _nsglChannels.find(channel);
944b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
945b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    if (it != _nsglChannels.end())
946b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    {
947b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        VideoChannelNSOpenGL* aglChannel = it->second;
948b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        if (aglChannel->SetStreamSettings(0, startWidth, startHeight, stopWidth, stopHeight) == -1)
949b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        {
950b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org            WEBRTC_TRACE(kTraceError, kTraceVideoRenderer, _id, "%s failed to set stream settings: channel %d. channel=%d zOrder=%d startWidth=%d startHeight=%d stopWidth=%d stopHeight=%d",
951b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                    __FUNCTION__, channel, zOrder, startWidth, startHeight, stopWidth, stopHeight);
952b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org            return NULL;
953b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        }
954b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        WEBRTC_TRACE(kTraceInfo, kTraceVideoRenderer, _id, "%s Configuring channel %d. channel=%d zOrder=%d startWidth=%d startHeight=%d stopWidth=%d stopHeight=%d",
955b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                __FUNCTION__, channel, zOrder, startWidth, startHeight, stopWidth, stopHeight);
956b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
957b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        std::multimap<int, int>::iterator it = _zOrderToChannel.begin();
958b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        while(it != _zOrderToChannel.end())
959b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        {
960b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org            if (it->second == channel)
961b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org            {
962b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                if (it->first != zOrder)
963b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                {
964b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                    _zOrderToChannel.erase(it);
965b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                    _zOrderToChannel.insert(std::pair<int, int>(zOrder, channel));
966b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                }
967b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org                break;
968b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org            }
969b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org            it++;
970b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        }
971b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        return aglChannel;
972b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    }
973b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
974b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    return NULL;
975b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
976b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
977b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org/*
978b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org *
979b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org *    Rendering process
980b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org *
981b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org */
982b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
983b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgbool VideoRenderNSOpenGL::ScreenUpdateThreadProc(void* obj)
984b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{
985b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    return static_cast<VideoRenderNSOpenGL*>(obj)->ScreenUpdateProcess();
986b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
987b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
988b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgbool VideoRenderNSOpenGL::ScreenUpdateProcess()
989b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{
990b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
991b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    _screenUpdateEvent->Wait(10);
992b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    LockAGLCntx();
993b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
994b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    if (!_screenUpdateThread)
995b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    {
996b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        WEBRTC_TRACE(kTraceWarning, kTraceVideoRenderer, _id, "%s no screen update thread", __FUNCTION__);
997b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        UnlockAGLCntx();
998b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        return false;
999b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    }
1000b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
1001b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    [_nsglContext makeCurrentContext];
1002b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
1003b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    if (GetWindowRect(_windowRect) == -1)
1004b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    {
1005b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        UnlockAGLCntx();
1006b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        return true;
1007b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    }
1008b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
1009b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    if (_windowWidth != (_windowRect.right - _windowRect.left)
1010b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org            || _windowHeight != (_windowRect.bottom - _windowRect.top))
1011b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    {
1012b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        _windowWidth = _windowRect.right - _windowRect.left;
1013b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        _windowHeight = _windowRect.bottom - _windowRect.top;
1014b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        glViewport(0, 0, _windowWidth, _windowHeight);
1015b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    }
1016b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
1017b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    // Check if there are any updated buffers
1018b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    bool updated = false;
1019b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    std::map<int, VideoChannelNSOpenGL*>::iterator it = _nsglChannels.begin();
1020b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    while (it != _nsglChannels.end())
1021b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    {
1022b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
1023b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        VideoChannelNSOpenGL* aglChannel = it->second;
1024b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        aglChannel->UpdateStretchSize(_windowHeight, _windowWidth);
1025b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        aglChannel->IsUpdated(updated);
1026b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        if (updated)
1027b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        {
1028b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org            break;
1029b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        }
1030b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        it++;
1031b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    }
1032b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
1033b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    if (updated)
1034b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    {
1035b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
1036b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        // At least on buffers is updated, we need to repaint the texture
1037b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        if (RenderOffScreenBuffers() != -1)
1038b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        {
1039b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org            UnlockAGLCntx();
1040b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org            return true;
1041b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        }
1042b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    }
1043b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    //    }
1044b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    UnlockAGLCntx();
1045b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    return true;
1046b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
1047b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
1048b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org/*
1049b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org *
1050b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org *    Functions for creating mixing buffers and screen settings
1051b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org *
1052b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org */
1053b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
1054b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgint VideoRenderNSOpenGL::CreateMixingContext()
1055b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{
1056b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
1057b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    CriticalSectionScoped cs(&_nsglContextCritSec);
1058b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
1059b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    if(_fullScreen)
1060b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    {
1061b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        if(-1 == setRenderTargetFullScreen())
1062b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        {
1063b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org            return -1;
1064b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        }
1065b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    }
1066b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    else
1067b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    {
1068b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
1069b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        if(-1 == setRenderTargetWindow())
1070b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        {
1071b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org            return -1;
1072b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        }
1073b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    }
1074b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
1075b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    configureNSOpenGLEngine();
1076b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
1077b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    DisplayBuffers();
1078b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
1079b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    GLenum glErr = glGetError();
1080b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    if (glErr)
1081b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    {
1082b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    }
1083b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
1084b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    return 0;
1085b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
1086b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
1087b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org/*
1088b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org *
1089b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org *    Rendering functions
1090b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org *
1091b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org */
1092b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
1093b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgint VideoRenderNSOpenGL::RenderOffScreenBuffers()
1094b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{
1095b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    LockAGLCntx();
1096b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
1097b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    // Get the current window size, it might have changed since last render.
1098b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    if (GetWindowRect(_windowRect) == -1)
1099b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    {
1100b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        UnlockAGLCntx();
1101b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        return -1;
1102b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    }
1103b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
1104b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    [_nsglContext makeCurrentContext];
1105b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    glClear(GL_COLOR_BUFFER_BIT);
1106b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
1107b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    // Loop through all channels starting highest zOrder ending with lowest.
1108b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    for (std::multimap<int, int>::reverse_iterator rIt = _zOrderToChannel.rbegin();
1109b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org            rIt != _zOrderToChannel.rend();
1110b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org            rIt++)
1111b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    {
1112b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        int channelId = rIt->second;
1113b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        std::map<int, VideoChannelNSOpenGL*>::iterator it = _nsglChannels.find(channelId);
1114b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
1115b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        VideoChannelNSOpenGL* aglChannel = it->second;
1116b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
1117b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        aglChannel->RenderOffScreenBuffer();
1118b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    }
1119b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
1120b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    DisplayBuffers();
1121b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
1122b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    UnlockAGLCntx();
1123b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    return 0;
1124b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
1125b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
1126b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org/*
1127b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org *
1128b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * Help functions
1129b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org *
1130b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org * All help functions assumes external protections
1131b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org *
1132b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org */
1133b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
1134b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgint VideoRenderNSOpenGL::DisplayBuffers()
1135b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{
1136b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
1137b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    LockAGLCntx();
1138b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
1139b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    glFinish();
1140b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    [_nsglContext flushBuffer];
1141b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
1142b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    WEBRTC_TRACE(kTraceDebug, kTraceVideoRenderer, _id, "%s glFinish and [_nsglContext flushBuffer]", __FUNCTION__);
1143b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
1144b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    UnlockAGLCntx();
1145b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    return 0;
1146b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
1147b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
1148b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgint VideoRenderNSOpenGL::GetWindowRect(Rect& rect)
1149b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{
1150b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
1151b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    CriticalSectionScoped cs(&_nsglContextCritSec);
1152b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
1153b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    if (_windowRef)
1154b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    {
1155b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        if(_fullScreen)
1156b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        {
1157b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org            NSRect mainDisplayRect = [[NSScreen mainScreen] frame];
1158b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org            rect.bottom = 0;
1159b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org            rect.left = 0;
1160b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org            rect.right = mainDisplayRect.size.width;
1161b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org            rect.top = mainDisplayRect.size.height;
1162b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        }
1163b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        else
1164b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        {
1165b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org            rect.top = [_windowRef frame].origin.y;
1166b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org            rect.left = [_windowRef frame].origin.x;
1167b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org            rect.bottom = [_windowRef frame].origin.y + [_windowRef frame].size.height;
1168b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org            rect.right = [_windowRef frame].origin.x + [_windowRef frame].size.width;
1169b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        }
1170b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
1171b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        return 0;
1172b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    }
1173b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    else
1174b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    {
1175b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org        return -1;
1176b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    }
1177b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
1178b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
1179e1ca446434022ad0d05ebd5ed2feafb08ae940e3pbos@webrtc.orgint32_t VideoRenderNSOpenGL::ChangeUniqueID(int32_t id)
1180b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{
1181b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
1182b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    CriticalSectionScoped cs(&_nsglContextCritSec);
1183b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    _id = id;
1184b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    return 0;
1185b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
1186b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
1187e1ca446434022ad0d05ebd5ed2feafb08ae940e3pbos@webrtc.orgint32_t VideoRenderNSOpenGL::SetText(const uint8_t /*textId*/,
1188e1ca446434022ad0d05ebd5ed2feafb08ae940e3pbos@webrtc.org                                     const uint8_t* /*text*/,
1189e1ca446434022ad0d05ebd5ed2feafb08ae940e3pbos@webrtc.org                                     const int32_t /*textLength*/,
1190e1ca446434022ad0d05ebd5ed2feafb08ae940e3pbos@webrtc.org                                     const uint32_t /*textColorRef*/,
1191e1ca446434022ad0d05ebd5ed2feafb08ae940e3pbos@webrtc.org                                     const uint32_t /*backgroundColorRef*/,
1192e1ca446434022ad0d05ebd5ed2feafb08ae940e3pbos@webrtc.org                                     const float /*left*/,
1193e1ca446434022ad0d05ebd5ed2feafb08ae940e3pbos@webrtc.org                                     const float /*top*/,
1194e1ca446434022ad0d05ebd5ed2feafb08ae940e3pbos@webrtc.org                                     const float /*right*/,
1195e1ca446434022ad0d05ebd5ed2feafb08ae940e3pbos@webrtc.org                                     const float /*bottom*/)
1196b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{
1197b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
1198b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    return 0;
1199b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
1200b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
1201b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
1202b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgvoid VideoRenderNSOpenGL::LockAGLCntx()
1203b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{
1204b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    _nsglContextCritSec.Enter();
1205b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
1206b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.orgvoid VideoRenderNSOpenGL::UnlockAGLCntx()
1207b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org{
1208b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    _nsglContextCritSec.Leave();
1209b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
1210b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
1211b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org/*
1212b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
1213b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org bool VideoRenderNSOpenGL::SetFullScreen(bool fullscreen)
1214b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org {
1215b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org NSRect mainDisplayRect, viewRect;
1216b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
1217b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // Create a screen-sized window on the display you want to take over
1218b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // Note, mainDisplayRect has a non-zero origin if the key window is on a secondary display
1219b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org mainDisplayRect = [[NSScreen mainScreen] frame];
1220b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org fullScreenWindow = [[NSWindow alloc] initWithContentRect:mainDisplayRect styleMask:NSBorderlessWindowMask
1221b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org backing:NSBackingStoreBuffered defer:YES];
1222b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
1223b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // Set the window level to be above the menu bar
1224b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org [fullScreenWindow setLevel:NSMainMenuWindowLevel+1];
1225b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
1226b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // Perform any other window configuration you desire
1227b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org [fullScreenWindow setOpaque:YES];
1228b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org [fullScreenWindow setHidesOnDeactivate:YES];
1229b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
1230b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // Create a view with a double-buffered OpenGL context and attach it to the window
1231b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // By specifying the non-fullscreen context as the shareContext, we automatically inherit the OpenGL objects (textures, etc) it has defined
1232b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org viewRect = NSMakeRect(0.0, 0.0, mainDisplayRect.size.width, mainDisplayRect.size.height);
1233b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org fullScreenView = [[MyOpenGLView alloc] initWithFrame:viewRect shareContext:[openGLView openGLContext]];
1234b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org [fullScreenWindow setContentView:fullScreenView];
1235b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
1236b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // Show the window
1237b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org [fullScreenWindow makeKeyAndOrderFront:self];
1238b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
1239b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // Set the scene with the full-screen viewport and viewing transformation
1240b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org [scene setViewportRect:viewRect];
1241b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
1242b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // Assign the view's MainController to self
1243b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org [fullScreenView setMainController:self];
1244b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
1245b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org if (!isAnimating) {
1246b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // Mark the view as needing drawing to initalize its contents
1247b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org [fullScreenView setNeedsDisplay:YES];
1248b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org }
1249b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org else {
1250b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org // Start playing the animation
1251b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org [fullScreenView startAnimation];
1252b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org }
1253b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
1254b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org }
1255b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
1256b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
1257b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
1258b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org */
1259b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
1260b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
12613b89e10f31160da35b408fd00cb8f89d2b08862dpbos@webrtc.org}  // namespace webrtc
1262b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
1263b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org#endif // COCOA_RENDERING
1264