Skip to content

Commit 81d9a72

Browse files
author
Thayer J Andrews
committed
CCEffectHue - Recompute the color matrix as needed instead of on every draw
This was motivated by the following performance findings on an iPhone 4s. Original implementation: 26fps / 20% CPU usage Color matrix implementation: `60fps / 44% CPU usage Interestingly even removing the matrix computation on every draw, the CPU usage is still ~44%. Since the change doesn't add much complexity I'm keeping it but I'm surprised it had no impact on CPU usage.
1 parent c8848b0 commit 81d9a72

File tree

1 file changed

+46
-26
lines changed

1 file changed

+46
-26
lines changed

cocos2d/CCEffectHue.m

Lines changed: 46 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -50,10 +50,17 @@
5050
#if CC_ENABLE_EXPERIMENTAL_EFFECTS
5151
static float conditionHue(float hue);
5252

53-
@interface CCEffectHue ()
53+
#if CCEFFECTHUE_USES_COLOR_MATRIX
54+
static GLKMatrix4 matrixWithHue(float hue);
55+
#endif
5456

55-
@property (nonatomic) float conditionedHue;
5657

58+
@interface CCEffectHue ()
59+
#if CCEFFECTHUE_USES_COLOR_MATRIX
60+
@property (nonatomic) GLKMatrix4 hueRotationMtx;
61+
#else
62+
@property (nonatomic) float conditionedHue;
63+
#endif
5764
@end
5865

5966

@@ -77,8 +84,11 @@ -(id)initWithHue:(float)hue
7784
if((self = [super initWithFragmentUniforms:uniforms vertexUniforms:nil varying:nil]))
7885
{
7986
_hue = hue;
87+
#if CCEFFECTHUE_USES_COLOR_MATRIX
88+
_hueRotationMtx = matrixWithHue(conditionHue(hue));
89+
#else
8090
_conditionedHue = conditionHue(hue);
81-
91+
#endif
8292
self.debugName = @"CCEffectHue";
8393
}
8494
return self;
@@ -155,29 +165,7 @@ -(void)buildRenderPasses
155165
pass.shaderUniforms[CCShaderUniformMainTexture] = previousPassTexture;
156166
pass.shaderUniforms[CCShaderUniformPreviousPassTexture] = previousPassTexture;
157167
#if CCEFFECTHUE_USES_COLOR_MATRIX
158-
// RGB to YIQ and YIQ to RGB matrix values source from here:
159-
// https://github.com/BradLarson/GPUImage/blob/master/framework/Source/GPUImageHueFilter.m
160-
// And here:
161-
// http://en.wikipedia.org/wiki/YIQ
162-
//
163-
// Note that GL matrices are column major so our matrices are transposed relative to the
164-
// reference implementations when loaded as they are below. I'm leaving them like this to
165-
// improve readability for comparison purposes and I handle the transpose by doing color * mtx
166-
// in the shader instead of mtx * color. The order that the matrices are composed below is
167-
// also reversed to account for the left multiply of the color value.
168-
169-
GLKMatrix4 rgbToYiq = GLKMatrix4Make(0.299, 0.587, 0.114, 0.0,
170-
0.595716, -0.274453, -0.321263, 0.0,
171-
0.211456, -0.522591, 0.31135, 0.0,
172-
0.0, 0.0, 0.0, 1.0);
173-
GLKMatrix4 yiqToRgb = GLKMatrix4Make(1.0, 0.9563, 0.6210, 0.0,
174-
1.0, -0.2721, -0.6474, 0.0,
175-
1.0, -1.1070, 1.7046, 0.0,
176-
0.0, 0.0, 0.0, 1.0);
177-
GLKMatrix4 rotation = GLKMatrix4MakeRotation(_conditionedHue, 1.0f, 0.0f, 0.0f);
178-
GLKMatrix4 composed = GLKMatrix4Multiply(rgbToYiq, GLKMatrix4Multiply(rotation, yiqToRgb));
179-
180-
pass.shaderUniforms[weakSelf.uniformTranslationTable[@"u_hueRotationMtx"]] = [NSValue valueWithGLKMatrix4:composed];
168+
pass.shaderUniforms[weakSelf.uniformTranslationTable[@"u_hueRotationMtx"]] = [NSValue valueWithGLKMatrix4:weakSelf.hueRotationMtx];
181169
#else
182170
pass.shaderUniforms[weakSelf.uniformTranslationTable[@"u_hue"]] = [NSNumber numberWithFloat:weakSelf.conditionedHue];
183171
#endif
@@ -189,7 +177,11 @@ -(void)buildRenderPasses
189177
-(void)setHue:(float)hue
190178
{
191179
_hue = hue;
180+
#if CCEFFECTHUE_USES_COLOR_MATRIX
181+
_hueRotationMtx = matrixWithHue(conditionHue(hue));
182+
#else
192183
_conditionedHue = conditionHue(hue);
184+
#endif
193185
}
194186

195187
@end
@@ -200,4 +192,32 @@ float conditionHue(float hue)
200192
return clampf(hue, -180.0f, 180.0f) * M_PI / 180.0f;
201193
}
202194

195+
#if CCEFFECTHUE_USES_COLOR_MATRIX
196+
GLKMatrix4 matrixWithHue(float hue)
197+
{
198+
// RGB to YIQ and YIQ to RGB matrix values source from here:
199+
// https://github.com/BradLarson/GPUImage/blob/master/framework/Source/GPUImageHueFilter.m
200+
// And here:
201+
// http://en.wikipedia.org/wiki/YIQ
202+
//
203+
// Note that GL matrices are column major so our matrices are transposed relative to the
204+
// reference implementations when loaded as they are below. I'm leaving them like this to
205+
// improve readability for comparison purposes and I handle the transpose by doing color * mtx
206+
// in the shader instead of mtx * color. The order that the matrices are composed below is
207+
// also reversed to account for the left multiply of the color value.
208+
209+
GLKMatrix4 rgbToYiq = GLKMatrix4Make(0.299, 0.587, 0.114, 0.0,
210+
0.595716, -0.274453, -0.321263, 0.0,
211+
0.211456, -0.522591, 0.31135, 0.0,
212+
0.0, 0.0, 0.0, 1.0);
213+
GLKMatrix4 yiqToRgb = GLKMatrix4Make(1.0, 0.9563, 0.6210, 0.0,
214+
1.0, -0.2721, -0.6474, 0.0,
215+
1.0, -1.1070, 1.7046, 0.0,
216+
0.0, 0.0, 0.0, 1.0);
217+
GLKMatrix4 rotation = GLKMatrix4MakeRotation(hue, 1.0f, 0.0f, 0.0f);
218+
GLKMatrix4 composed = GLKMatrix4Multiply(rgbToYiq, GLKMatrix4Multiply(rotation, yiqToRgb));
219+
return composed;
220+
}
221+
#endif
222+
203223
#endif

0 commit comments

Comments
 (0)