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

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

Issue 2869143002: iOS: Add interface for injecting custom shaders (Closed)
Patch Set: Clean 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);
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 glDeleteProgram(_i420Program);
sakal 2017/05/11 10:45:47 Log error?
magjed_webrtc 2017/05/11 12:38:06 Done.
100 _i420Program = 0;
101 return NO;
102 }
103
104 glUseProgram(_i420Program);
105 glUniform1i(ySampler, kYTextureUnit);
106 glUniform1i(uSampler, kUTextureUnit);
107 glUniform1i(vSampler, kVTextureUnit);
108
109 return YES;
110 }
111
112 - (BOOL)setupNV12Program {
113 _nv12Program = RTCCreateProgramFromFragmentSource(kNV12FragmentShaderSource);
114 if (!_nv12Program) {
115 return NO;
116 }
117 GLint ySampler = glGetUniformLocation(_nv12Program, "s_textureY");
118 GLint uvSampler = glGetUniformLocation(_nv12Program, "s_textureUV");
119
120 if (ySampler < 0 || uvSampler < 0) {
121 glDeleteProgram(_nv12Program);
122 _nv12Program = 0;
123 return NO;
124 }
125
126 glUseProgram(_nv12Program);
127 glUniform1i(ySampler, kYTextureUnit);
128 glUniform1i(uvSampler, kUvTextureUnit);
129
130 return YES;
131 }
132
133 - (BOOL)prepareVertexBufferWithRotation:(RTCVideoRotation)rotation {
134 if (!_vertexBuffer && !RTCCreateVertexBuffer(&_vertexBuffer, &_vertexArray)) {
135 RTCLog(@"Failed to setup vertex buffer");
136 return NO;
137 }
138 #if !TARGET_OS_IPHONE
139 glBindVertexArray(_vertexArray);
140 #endif
141 glBindBuffer(GL_ARRAY_BUFFER, _vertexBuffer);
142 if (!_currentRotation || rotation != *_currentRotation) {
143 _currentRotation = rtc::Optional<RTCVideoRotation>(rotation);
144 RTCSetVertexData(*_currentRotation);
145 }
146 return YES;
147 }
148
149 - (void)videoView:(RTCVideoView *)videoView
150 didReceiveFrameWithRotation:(RTCVideoRotation)rotation
151 yPlane:(GLuint)yPlane
152 uPlane:(GLuint)uPlane
153 vPlane:(GLuint)vPlane {
154 if (![self prepareVertexBufferWithRotation:rotation]) {
155 return;
156 }
157
158 if (!_i420Program && ![self setupI420Program]) {
159 RTCLog(@"Failed to setup I420 program");
160 return;
161 }
162
163 glUseProgram(_i420Program);
164
165 glActiveTexture(static_cast<GLenum>(GL_TEXTURE0 + kYTextureUnit));
166 glBindTexture(GL_TEXTURE_2D, yPlane);
167
168 glActiveTexture(static_cast<GLenum>(GL_TEXTURE0 + kUTextureUnit));
169 glBindTexture(GL_TEXTURE_2D, uPlane);
170
171 glActiveTexture(static_cast<GLenum>(GL_TEXTURE0 + kVTextureUnit));
172 glBindTexture(GL_TEXTURE_2D, vPlane);
173
174 glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
175 }
176
177 - (void)videoView:(RTCVideoView *)videoView
178 didReceiveFrameWithRotation:(RTCVideoRotation)rotation
179 yPlane:(GLuint)yPlane
180 uvPlane:(GLuint)uvPlane {
181 if (![self prepareVertexBufferWithRotation:rotation]) {
182 return;
183 }
184
185 if (!_nv12Program && ![self setupNV12Program]) {
186 RTCLog(@"Failed to setup NV12 shader");
187 return;
188 }
189
190 glUseProgram(_nv12Program);
191
192 glActiveTexture(static_cast<GLenum>(GL_TEXTURE0 + kYTextureUnit));
193 glBindTexture(GL_TEXTURE_2D, yPlane);
194
195 glActiveTexture(static_cast<GLenum>(GL_TEXTURE0 + kUvTextureUnit));
196 glBindTexture(GL_TEXTURE_2D, uvPlane);
197
198 glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
199 }
200
201 @end
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698