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

Side by Side Diff: webrtc/sdk/objc/Framework/Classes/RTCDefaultShaderDelegate.mm

Issue 2869143002: iOS: Add interface for injecting custom shaders (Closed)
Patch Set: Address comments. Created 3 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 /*
2 * Copyright 2017 The WebRTC project authors. All Rights Reserved.
3 *
4 * Use of this source code is governed by a BSD-style license
5 * that can be found in the LICENSE file in the root of the source
6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree.
9 */
10
11 #import "RTCDefaultShaderDelegate.h"
12
13 #if TARGET_OS_IPHONE
14 #import <OpenGLES/ES3/gl.h>
15 #else
16 #import <OpenGL/gl3.h>
17 #endif
18
19 #import "RTCOpenGLDefines.h"
20 #import "RTCShader.h"
21 #import "WebRTC/RTCLogging.h"
22
23 #include "webrtc/base/optional.h"
24
25 static const int kYTextureUnit = 0;
26 static const int kUTextureUnit = 1;
27 static const int kVTextureUnit = 2;
28 static const int kUvTextureUnit = 1;
29
30 // Fragment shader converts YUV values from input textures into a final RGB
31 // pixel. The conversion formula is from http://www.fourcc.org/fccyvrgb.php.
32 static const char kI420FragmentShaderSource[] =
33 SHADER_VERSION
34 "precision highp float;"
35 FRAGMENT_SHADER_IN " vec2 v_texcoord;\n"
36 "uniform lowp sampler2D s_textureY;\n"
37 "uniform lowp sampler2D s_textureU;\n"
38 "uniform lowp sampler2D s_textureV;\n"
39 FRAGMENT_SHADER_OUT
40 "void main() {\n"
41 " float y, u, v, r, g, b;\n"
42 " y = " FRAGMENT_SHADER_TEXTURE "(s_textureY, v_texcoord).r;\n"
43 " u = " FRAGMENT_SHADER_TEXTURE "(s_textureU, v_texcoord).r;\n"
44 " v = " FRAGMENT_SHADER_TEXTURE "(s_textureV, v_texcoord).r;\n"
45 " u = u - 0.5;\n"
46 " v = v - 0.5;\n"
47 " r = y + 1.403 * v;\n"
48 " g = y - 0.344 * u - 0.714 * v;\n"
49 " b = y + 1.770 * u;\n"
50 " " FRAGMENT_SHADER_COLOR " = vec4(r, g, b, 1.0);\n"
51 " }\n";
52
53 static const char kNV12FragmentShaderSource[] =
54 SHADER_VERSION
55 "precision mediump float;"
56 FRAGMENT_SHADER_IN " vec2 v_texcoord;\n"
57 "uniform lowp sampler2D s_textureY;\n"
58 "uniform lowp sampler2D s_textureUV;\n"
59 FRAGMENT_SHADER_OUT
60 "void main() {\n"
61 " mediump float y;\n"
62 " mediump vec2 uv;\n"
63 " y = " FRAGMENT_SHADER_TEXTURE "(s_textureY, v_texcoord).r;\n"
64 " uv = " FRAGMENT_SHADER_TEXTURE "(s_textureUV, v_texcoord).ra -\n"
65 " vec2(0.5, 0.5);\n"
66 " " FRAGMENT_SHADER_COLOR " = vec4(y + 1.403 * uv.y,\n"
67 " y - 0.344 * uv.x - 0.714 * uv.y,\n"
68 " y + 1.770 * uv.x,\n"
69 " 1.0);\n"
70 " }\n";
71
72 @implementation RTCDefaultShaderDelegate {
73 GLuint _vertexBuffer;
74 GLuint _vertexArray;
75 // Store current rotation and only upload new vertex data when rotation change s.
76 rtc::Optional<RTCVideoRotation> _currentRotation;
77
78 GLuint _i420Program;
79 GLuint _nv12Program;
80 }
81
82 - (void)dealloc {
83 glDeleteProgram(_i420Program);
84 glDeleteProgram(_nv12Program);
85 glDeleteBuffers(1, &_vertexBuffer);
86 glDeleteVertexArrays(1, &_vertexArray);
87 }
88
89 - (BOOL)setupI420Program {
90 _i420Program = RTCCreateProgramFromFragmentSource(kI420FragmentShaderSource);
daniela-webrtc 2017/05/11 17:31:20 Should we check if the program already exists? If
magjed_webrtc 2017/05/25 14:26:45 Added assert and changed the name.
91 if (!_i420Program) {
92 return NO;
93 }
94 GLint ySampler = glGetUniformLocation(_i420Program, "s_textureY");
95 GLint uSampler = glGetUniformLocation(_i420Program, "s_textureU");
96 GLint vSampler = glGetUniformLocation(_i420Program, "s_textureV");
97
98 if (ySampler < 0 || uSampler < 0 || vSampler < 0) {
99 RTCLog(@"Failed to get uniform variable locations in I420 shader");
100 glDeleteProgram(_i420Program);
101 _i420Program = 0;
102 return NO;
103 }
104
105 glUseProgram(_i420Program);
106 glUniform1i(ySampler, kYTextureUnit);
107 glUniform1i(uSampler, kUTextureUnit);
108 glUniform1i(vSampler, kVTextureUnit);
109
110 return YES;
111 }
112
113 - (BOOL)setupNV12Program {
114 _nv12Program = RTCCreateProgramFromFragmentSource(kNV12FragmentShaderSource);
daniela-webrtc 2017/05/11 17:31:20 ^
magjed_webrtc 2017/05/25 14:26:45 Done.
115 if (!_nv12Program) {
116 return NO;
117 }
118 GLint ySampler = glGetUniformLocation(_nv12Program, "s_textureY");
119 GLint uvSampler = glGetUniformLocation(_nv12Program, "s_textureUV");
120
121 if (ySampler < 0 || uvSampler < 0) {
122 RTCLog(@"Failed to get uniform variable locations in NV12 shader");
123 glDeleteProgram(_nv12Program);
124 _nv12Program = 0;
125 return NO;
126 }
127
128 glUseProgram(_nv12Program);
129 glUniform1i(ySampler, kYTextureUnit);
130 glUniform1i(uvSampler, kUvTextureUnit);
131
132 return YES;
133 }
134
135 - (BOOL)prepareVertexBufferWithRotation:(RTCVideoRotation)rotation {
136 if (!_vertexBuffer && !RTCCreateVertexBuffer(&_vertexBuffer, &_vertexArray)) {
137 RTCLog(@"Failed to setup vertex buffer");
138 return NO;
139 }
140 #if !TARGET_OS_IPHONE
141 glBindVertexArray(_vertexArray);
142 #endif
143 glBindBuffer(GL_ARRAY_BUFFER, _vertexBuffer);
144 if (!_currentRotation || rotation != *_currentRotation) {
145 _currentRotation = rtc::Optional<RTCVideoRotation>(rotation);
146 RTCSetVertexData(*_currentRotation);
147 }
148 return YES;
149 }
150
151 - (void)videoView:(RTCVideoView *)videoView
152 didReceiveFrameWithRotation:(RTCVideoRotation)rotation
153 yPlane:(GLuint)yPlane
154 uPlane:(GLuint)uPlane
155 vPlane:(GLuint)vPlane {
156 if (![self prepareVertexBufferWithRotation:rotation]) {
157 return;
158 }
159
160 if (!_i420Program && ![self setupI420Program]) {
161 RTCLog(@"Failed to setup I420 program");
162 return;
163 }
164
165 glUseProgram(_i420Program);
166
167 glActiveTexture(static_cast<GLenum>(GL_TEXTURE0 + kYTextureUnit));
168 glBindTexture(GL_TEXTURE_2D, yPlane);
169
170 glActiveTexture(static_cast<GLenum>(GL_TEXTURE0 + kUTextureUnit));
171 glBindTexture(GL_TEXTURE_2D, uPlane);
172
173 glActiveTexture(static_cast<GLenum>(GL_TEXTURE0 + kVTextureUnit));
174 glBindTexture(GL_TEXTURE_2D, vPlane);
175
176 glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
177 }
178
179 - (void)videoView:(RTCVideoView *)videoView
180 didReceiveFrameWithRotation:(RTCVideoRotation)rotation
181 yPlane:(GLuint)yPlane
182 uvPlane:(GLuint)uvPlane {
183 if (![self prepareVertexBufferWithRotation:rotation]) {
184 return;
185 }
186
187 if (!_nv12Program && ![self setupNV12Program]) {
188 RTCLog(@"Failed to setup NV12 shader");
189 return;
190 }
191
192 glUseProgram(_nv12Program);
193
194 glActiveTexture(static_cast<GLenum>(GL_TEXTURE0 + kYTextureUnit));
195 glBindTexture(GL_TEXTURE_2D, yPlane);
196
197 glActiveTexture(static_cast<GLenum>(GL_TEXTURE0 + kUvTextureUnit));
198 glBindTexture(GL_TEXTURE_2D, uvPlane);
199
200 glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
201 }
202
203 @end
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698