| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright 2015 Google Inc. | 2 * Copyright 2015 Google Inc. |
| 3 * | 3 * |
| 4 * Use of this source code is governed by a BSD-style license that can be | 4 * Use of this source code is governed by a BSD-style license that can be |
| 5 * found in the LICENSE file. | 5 * found in the LICENSE file. |
| 6 */ | 6 */ |
| 7 | 7 |
| 8 #include "Test.h" | 8 #include "Test.h" |
| 9 #if SK_SUPPORT_GPU | 9 #if SK_SUPPORT_GPU |
| 10 #include "GrCaps.h" |
| 11 #include "GrContext.h" |
| 10 #include "SkCanvas.h" | 12 #include "SkCanvas.h" |
| 11 | |
| 12 #include "SkSurface.h" | 13 #include "SkSurface.h" |
| 13 #include "GrContextFactory.h" | |
| 14 #include "GrCaps.h" | |
| 15 | 14 |
| 16 // using anonymous namespace because these functions are used as template params
. | 15 // using anonymous namespace because these functions are used as template params
. |
| 17 namespace { | 16 namespace { |
| 18 /** convert 0..1 srgb value to 0..1 linear */ | 17 /** convert 0..1 srgb value to 0..1 linear */ |
| 19 float srgb_to_linear(float srgb) { | 18 float srgb_to_linear(float srgb) { |
| 20 if (srgb <= 0.04045f) { | 19 if (srgb <= 0.04045f) { |
| 21 return srgb / 12.92f; | 20 return srgb / 12.92f; |
| 22 } else { | 21 } else { |
| 23 return powf((srgb + 0.055f) / 1.055f, 2.4f); | 22 return powf((srgb + 0.055f) / 1.055f, 2.4f); |
| 24 } | 23 } |
| (...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 132 ERRORF(reporter, "Expected 0x%08x, read back as 0x%08x in %s at
%d, %d).", | 131 ERRORF(reporter, "Expected 0x%08x, read back as 0x%08x in %s at
%d, %d).", |
| 133 orig, read, subtestName, i, j); | 132 orig, read, subtestName, i, j); |
| 134 return; | 133 return; |
| 135 } | 134 } |
| 136 } | 135 } |
| 137 } | 136 } |
| 138 } | 137 } |
| 139 | 138 |
| 140 // TODO: Add tests for copySurface between srgb/linear textures. Add tests for u
npremul/premul | 139 // TODO: Add tests for copySurface between srgb/linear textures. Add tests for u
npremul/premul |
| 141 // conversion during read/write along with srgb/linear conversions. | 140 // conversion during read/write along with srgb/linear conversions. |
| 142 DEF_GPUTEST(SRGBReadWritePixels, reporter, factory) { | 141 DEF_GPUTEST_FOR_RENDERING_CONTEXTS(SRGBReadWritePixels, reporter, context) { |
| 143 #if defined(GOOGLE3) | 142 #if defined(GOOGLE3) |
| 144 // Stack frame size is limited in GOOGLE3. | 143 // Stack frame size is limited in GOOGLE3. |
| 145 static const int kW = 63; | 144 static const int kW = 63; |
| 146 static const int kH = 63; | 145 static const int kH = 63; |
| 147 #else | 146 #else |
| 148 static const int kW = 255; | 147 static const int kW = 255; |
| 149 static const int kH = 255; | 148 static const int kH = 255; |
| 150 #endif | 149 #endif |
| 151 uint32_t origData[kW * kH]; | 150 uint32_t origData[kW * kH]; |
| 152 for (int j = 0; j < kH; ++j) { | 151 for (int j = 0; j < kH; ++j) { |
| 153 for (int i = 0; i < kW; ++i) { | 152 for (int i = 0; i < kW; ++i) { |
| 154 origData[j * kW + i] = (j << 24) | (i << 16) | (i << 8) | i; | 153 origData[j * kW + i] = (j << 24) | (i << 16) | (i << 8) | i; |
| 155 } | 154 } |
| 156 } | 155 } |
| 157 | 156 |
| 158 for (int t = 0; t < GrContextFactory::kGLContextTypeCnt; ++t) { | 157 GrSurfaceDesc desc; |
| 159 GrContextFactory::GLContextType glType = (GrContextFactory::GLContextTyp
e) t; | 158 desc.fFlags = kRenderTarget_GrSurfaceFlag; |
| 160 GrContext* context; | 159 desc.fWidth = kW; |
| 161 // We allow more error on GPUs with lower precision shader variables. | 160 desc.fHeight = kH; |
| 162 if (!GrContextFactory::IsRenderingGLContext(glType) || !(context = facto
ry->get(glType))) { | 161 desc.fConfig = kSRGBA_8888_GrPixelConfig; |
| 163 continue; | 162 if (context->caps()->isConfigRenderable(desc.fConfig, false) && |
| 163 context->caps()->isConfigTexturable(desc.fConfig)) { |
| 164 SkAutoTUnref<GrTexture> tex(context->textureProvider()->createTexture(de
sc, false)); |
| 165 if (!tex) { |
| 166 ERRORF(reporter, "Could not create SRGBA texture."); |
| 167 return; |
| 164 } | 168 } |
| 165 | 169 |
| 166 GrSurfaceDesc desc; | 170 float error = context->caps()->shaderCaps()->floatPrecisionVaries() ? 1.
2f : 0.5f; |
| 167 desc.fFlags = kRenderTarget_GrSurfaceFlag; | |
| 168 desc.fWidth = kW; | |
| 169 desc.fHeight = kH; | |
| 170 desc.fConfig = kSRGBA_8888_GrPixelConfig; | |
| 171 if (context->caps()->isConfigRenderable(desc.fConfig, false) && | |
| 172 context->caps()->isConfigTexturable(desc.fConfig)) { | |
| 173 SkAutoTUnref<GrTexture> tex(context->textureProvider()->createTextur
e(desc, false)); | |
| 174 if (!tex) { | |
| 175 ERRORF(reporter, "Could not create SRGBA texture."); | |
| 176 continue; | |
| 177 } | |
| 178 | 171 |
| 179 float error = context->caps()->shaderCaps()->floatPrecisionVaries()
? 1.2f : 0.5f; | 172 // Write srgba data and read as srgba and then as rgba |
| 173 if (tex->writePixels(0, 0, kW, kH, kSRGBA_8888_GrPixelConfig, origData))
{ |
| 174 // For the all-srgba case, we allow a small error only for devices t
hat have |
| 175 // precision variation because the srgba data gets converted to line
ar and back in |
| 176 // the shader. |
| 177 float smallError = context->caps()->shaderCaps()->floatPrecisionVari
es() ? 1.f : |
| 178 0.0f; |
| 179 read_and_check_pixels(reporter, tex, origData, kSRGBA_8888_GrPixelCo
nfig, |
| 180 check_srgb_to_linear_to_srgb_conversion, small
Error, |
| 181 "write/read srgba to srgba texture"); |
| 182 read_and_check_pixels(reporter, tex, origData, kRGBA_8888_GrPixelCon
fig, |
| 183 check_srgb_to_linear_conversion, error, |
| 184 "write srgba/read rgba with srgba texture"); |
| 185 } else { |
| 186 ERRORF(reporter, "Could not write srgba data to srgba texture."); |
| 187 } |
| 180 | 188 |
| 181 // Write srgba data and read as srgba and then as rgba | 189 // Now verify that we can write linear data |
| 182 if (tex->writePixels(0, 0, kW, kH, kSRGBA_8888_GrPixelConfig, origDa
ta)) { | 190 if (tex->writePixels(0, 0, kW, kH, kRGBA_8888_GrPixelConfig, origData))
{ |
| 183 // For the all-srgba case, we allow a small error only for devic
es that have | 191 // We allow more error on GPUs with lower precision shader variables
. |
| 184 // precision variation because the srgba data gets converted to
linear and back in | 192 read_and_check_pixels(reporter, tex, origData, kSRGBA_8888_GrPixelCo
nfig, |
| 185 // the shader. | 193 check_linear_to_srgb_conversion, error, |
| 186 float smallError = context->caps()->shaderCaps()->floatPrecision
Varies() ? 1.f : | 194 "write rgba/read srgba with srgba texture"); |
| 187
0.0f; | 195 read_and_check_pixels(reporter, tex, origData, kRGBA_8888_GrPixelCon
fig, |
| 188 read_and_check_pixels(reporter, tex, origData, kSRGBA_8888_GrPix
elConfig, | 196 check_linear_to_srgb_to_linear_conversion, err
or, |
| 189 check_srgb_to_linear_to_srgb_conversion, s
mallError, | 197 "write/read rgba with srgba texture"); |
| 190 "write/read srgba to srgba texture"); | 198 } else { |
| 191 read_and_check_pixels(reporter, tex, origData, kRGBA_8888_GrPixe
lConfig, | 199 ERRORF(reporter, "Could not write rgba data to srgba texture."); |
| 192 check_srgb_to_linear_conversion, error, | 200 } |
| 193 "write srgba/read rgba with srgba texture"
); | |
| 194 } else { | |
| 195 ERRORF(reporter, "Could not write srgba data to srgba texture.")
; | |
| 196 } | |
| 197 | 201 |
| 198 // Now verify that we can write linear data | 202 desc.fConfig = kRGBA_8888_GrPixelConfig; |
| 199 if (tex->writePixels(0, 0, kW, kH, kRGBA_8888_GrPixelConfig, origDat
a)) { | 203 tex.reset(context->textureProvider()->createTexture(desc, false)); |
| 200 // We allow more error on GPUs with lower precision shader varia
bles. | 204 if (!tex) { |
| 201 read_and_check_pixels(reporter, tex, origData, kSRGBA_8888_GrPix
elConfig, | 205 ERRORF(reporter, "Could not create RGBA texture."); |
| 202 check_linear_to_srgb_conversion, error, | 206 return; |
| 203 "write rgba/read srgba with srgba texture"
); | 207 } |
| 204 read_and_check_pixels(reporter, tex, origData, kRGBA_8888_GrPixe
lConfig, | |
| 205 check_linear_to_srgb_to_linear_conversion,
error, | |
| 206 "write/read rgba with srgba texture"); | |
| 207 } else { | |
| 208 ERRORF(reporter, "Could not write rgba data to srgba texture."); | |
| 209 } | |
| 210 | 208 |
| 211 desc.fConfig = kRGBA_8888_GrPixelConfig; | 209 // Write srgba data to a rgba texture and read back as srgba and rgba |
| 212 tex.reset(context->textureProvider()->createTexture(desc, false)); | 210 if (tex->writePixels(0, 0, kW, kH, kSRGBA_8888_GrPixelConfig, origData))
{ |
| 213 if (!tex) { | 211 read_and_check_pixels(reporter, tex, origData, kSRGBA_8888_GrPixelCo
nfig, |
| 214 ERRORF(reporter, "Could not create RGBA texture."); | 212 check_srgb_to_linear_to_srgb_conversion, error
, |
| 215 continue; | 213 "write/read srgba to rgba texture"); |
| 216 } | 214 read_and_check_pixels(reporter, tex, origData, kRGBA_8888_GrPixelCon
fig, |
| 215 check_srgb_to_linear_conversion, error, |
| 216 "write srgba/read rgba to rgba texture"); |
| 217 } else { |
| 218 ERRORF(reporter, "Could not write srgba data to rgba texture."); |
| 219 } |
| 217 | 220 |
| 218 // Write srgba data to a rgba texture and read back as srgba and rgb
a | 221 // Write rgba data to a rgba texture and read back as srgba |
| 219 if (tex->writePixels(0, 0, kW, kH, kSRGBA_8888_GrPixelConfig, origDa
ta)) { | 222 if (tex->writePixels(0, 0, kW, kH, kRGBA_8888_GrPixelConfig, origData))
{ |
| 220 read_and_check_pixels(reporter, tex, origData, kSRGBA_8888_GrPixe
lConfig, | 223 read_and_check_pixels(reporter, tex, origData, kSRGBA_8888_GrPixelCo
nfig, |
| 221 check_srgb_to_linear_to_srgb_conversion, e
rror, | 224 check_linear_to_srgb_conversion, 1.2f, |
| 222 "write/read srgba to rgba texture"); | 225 "write rgba/read srgba to rgba texture"); |
| 223 read_and_check_pixels(reporter, tex, origData, kRGBA_8888_GrPixel
Config, | 226 } else { |
| 224 check_srgb_to_linear_conversion, error, | 227 ERRORF(reporter, "Could not write rgba data to rgba texture."); |
| 225 "write srgba/read rgba to rgba texture"); | 228 } |
| 226 } else { | |
| 227 ERRORF(reporter, "Could not write srgba data to rgba texture."); | |
| 228 } | |
| 229 | |
| 230 // Write rgba data to a rgba texture and read back as srgba | |
| 231 if (tex->writePixels(0, 0, kW, kH, kRGBA_8888_GrPixelConfig, origDat
a)) { | |
| 232 read_and_check_pixels(reporter, tex, origData, kSRGBA_8888_GrPix
elConfig, | |
| 233 check_linear_to_srgb_conversion, 1.2f, | |
| 234 "write rgba/read srgba to rgba texture"); | |
| 235 } else { | |
| 236 ERRORF(reporter, "Could not write rgba data to rgba texture."); | |
| 237 } | |
| 238 } | |
| 239 } | 229 } |
| 240 } | 230 } |
| 241 #endif | 231 #endif |
| OLD | NEW |