| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright 2016 Google Inc. | 2 * Copyright 2016 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 "GrTextureToYUVPlanes.h" | 8 #include "GrTextureToYUVPlanes.h" |
| 9 #include "effects/GrSimpleTextureEffect.h" | 9 #include "effects/GrSimpleTextureEffect.h" |
| 10 #include "effects/GrYUVEffect.h" | 10 #include "effects/GrYUVEffect.h" |
| 11 #include "GrClip.h" | 11 #include "GrClip.h" |
| 12 #include "GrContext.h" | 12 #include "GrContext.h" |
| 13 #include "GrRenderTargetContext.h" | 13 #include "GrRenderTargetContext.h" |
| 14 #include "GrPaint.h" | 14 #include "GrPaint.h" |
| 15 #include "GrTextureProvider.h" | 15 #include "GrTextureProvider.h" |
| 16 #include "GrTextureProxy.h" |
| 16 | 17 |
| 17 namespace { | 18 namespace { |
| 18 using MakeFPProc = sk_sp<GrFragmentProcessor> (*)(sk_sp<GrFragmentProcessor>
, | 19 using MakeFPProc = sk_sp<GrFragmentProcessor> (*)(sk_sp<GrFragmentProcessor>
, |
| 19 SkYUVColorSpace colorSpace
); | 20 SkYUVColorSpace colorSpace
); |
| 20 }; | 21 }; |
| 21 | 22 |
| 22 static bool convert_texture(GrTexture* src, GrRenderTargetContext* dst, int dstW
, int dstH, | 23 static bool convert_texture(GrTexture* src, GrRenderTargetContext* dst, int dstW
, int dstH, |
| 23 SkYUVColorSpace colorSpace, MakeFPProc proc) { | 24 SkYUVColorSpace colorSpace, MakeFPProc proc) { |
| 24 | 25 |
| 25 SkScalar xScale = SkIntToScalar(src->width()) / dstW / src->width(); | 26 SkScalar xScale = SkIntToScalar(src->width()) / dstW / src->width(); |
| (...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 141 if (!convert_texture(texture, vRenderTargetContext.get(), | 142 if (!convert_texture(texture, vRenderTargetContext.get(), |
| 142 sizes[2].fWidth, sizes[2].fHeight, | 143 sizes[2].fWidth, sizes[2].fHeight, |
| 143 colorSpace, GrYUVEffect::MakeRGBToV)) { | 144 colorSpace, GrYUVEffect::MakeRGBToV)) { |
| 144 return false; | 145 return false; |
| 145 } | 146 } |
| 146 } | 147 } |
| 147 } | 148 } |
| 148 | 149 |
| 149 if (yuvRenderTargetContext) { | 150 if (yuvRenderTargetContext) { |
| 150 SkASSERT(sizes[0] == sizes[1] && sizes[1] == sizes[2]); | 151 SkASSERT(sizes[0] == sizes[1] && sizes[1] == sizes[2]); |
| 151 sk_sp<GrTexture> yuvTex(yuvRenderTargetContext->asTexture()); | 152 sk_sp<GrTextureProxy> yuvTex(yuvRenderTargetContext->asDeferredTextu
re()); |
| 152 SkASSERT(yuvTex); | 153 SkASSERT(yuvTex); |
| 153 SkISize yuvSize = sizes[0]; | 154 SkISize yuvSize = sizes[0]; |
| 154 // We have no kRGB_888 pixel format, so readback rgba and then copy
three channels. | 155 // We have no kRGB_888 pixel format, so readback rgba and then copy
three channels. |
| 155 SkAutoSTMalloc<128 * 128, uint32_t> tempYUV(yuvSize.fWidth * yuvSize
.fHeight); | 156 SkAutoSTMalloc<128 * 128, uint32_t> tempYUV(yuvSize.fWidth * yuvSize
.fHeight); |
| 156 if (!yuvTex->readPixels(0, 0, yuvSize.fWidth, yuvSize.fHeight, | 157 if (!yuvTex->readPixels(0, 0, yuvSize.fWidth, yuvSize.fHeight, |
| 157 kRGBA_8888_GrPixelConfig, tempYUV.get(), 0))
{ | 158 kRGBA_8888_GrPixelConfig, tempYUV.get(), 0))
{ |
| 158 return false; | 159 return false; |
| 159 } | 160 } |
| 160 size_t yRowBytes = rowBytes[0] ? rowBytes[0] : yuvSize.fWidth; | 161 size_t yRowBytes = rowBytes[0] ? rowBytes[0] : yuvSize.fWidth; |
| 161 size_t uRowBytes = rowBytes[1] ? rowBytes[1] : yuvSize.fWidth; | 162 size_t uRowBytes = rowBytes[1] ? rowBytes[1] : yuvSize.fWidth; |
| (...skipping 12 matching lines...) Expand all Loading... |
| 174 uint8_t* uLoc = ((uint8_t*)planes[1]) + j * uRowBytes + i; | 175 uint8_t* uLoc = ((uint8_t*)planes[1]) + j * uRowBytes + i; |
| 175 uint8_t* vLoc = ((uint8_t*)planes[2]) + j * vRowBytes + i; | 176 uint8_t* vLoc = ((uint8_t*)planes[2]) + j * vRowBytes + i; |
| 176 *yLoc = y; | 177 *yLoc = y; |
| 177 *uLoc = u; | 178 *uLoc = u; |
| 178 *vLoc = v; | 179 *vLoc = v; |
| 179 } | 180 } |
| 180 } | 181 } |
| 181 return true; | 182 return true; |
| 182 } else { | 183 } else { |
| 183 SkASSERT(yRenderTargetContext); | 184 SkASSERT(yRenderTargetContext); |
| 184 sk_sp<GrTexture> yTex(yRenderTargetContext->asTexture()); | 185 sk_sp<GrTextureProxy> yTex(yRenderTargetContext->asDeferredTexture()
); |
| 185 SkASSERT(yTex); | 186 SkASSERT(yTex); |
| 186 if (!yTex->readPixels(0, 0, sizes[0].fWidth, sizes[0].fHeight, | 187 if (!yTex->readPixels(0, 0, sizes[0].fWidth, sizes[0].fHeight, |
| 187 kAlpha_8_GrPixelConfig, planes[0], rowBytes[0]
)) { | 188 kAlpha_8_GrPixelConfig, planes[0], rowBytes[0]
)) { |
| 188 return false; | 189 return false; |
| 189 } | 190 } |
| 190 if (uvRenderTargetContext) { | 191 if (uvRenderTargetContext) { |
| 191 SkASSERT(sizes[1].fWidth == sizes[2].fWidth); | 192 SkASSERT(sizes[1].fWidth == sizes[2].fWidth); |
| 192 sk_sp<GrTexture> uvTex(uvRenderTargetContext->asTexture()); | 193 sk_sp<GrTextureProxy> uvTex(uvRenderTargetContext->asDeferredTex
ture()); |
| 193 SkASSERT(uvTex); | 194 SkASSERT(uvTex); |
| 194 SkISize uvSize = sizes[1]; | 195 SkISize uvSize = sizes[1]; |
| 195 // We have no kRG_88 pixel format, so readback rgba and then cop
y two channels. | 196 // We have no kRG_88 pixel format, so readback rgba and then cop
y two channels. |
| 196 SkAutoSTMalloc<128 * 128, uint32_t> tempUV(uvSize.fWidth * uvSiz
e.fHeight); | 197 SkAutoSTMalloc<128 * 128, uint32_t> tempUV(uvSize.fWidth * uvSiz
e.fHeight); |
| 197 if (!uvTex->readPixels(0, 0, uvSize.fWidth, uvSize.fHeight, | 198 if (!uvTex->readPixels(0, 0, uvSize.fWidth, uvSize.fHeight, |
| 198 kRGBA_8888_GrPixelConfig, tempUV.get(), 0
)) { | 199 kRGBA_8888_GrPixelConfig, tempUV.get(), 0
)) { |
| 199 return false; | 200 return false; |
| 200 } | 201 } |
| 201 | 202 |
| 202 size_t uRowBytes = rowBytes[1] ? rowBytes[1] : uvSize.fWidth; | 203 size_t uRowBytes = rowBytes[1] ? rowBytes[1] : uvSize.fWidth; |
| 203 size_t vRowBytes = rowBytes[2] ? rowBytes[2] : uvSize.fWidth; | 204 size_t vRowBytes = rowBytes[2] ? rowBytes[2] : uvSize.fWidth; |
| 204 if (uRowBytes < (size_t)uvSize.fWidth || vRowBytes < (size_t)uvS
ize.fWidth) { | 205 if (uRowBytes < (size_t)uvSize.fWidth || vRowBytes < (size_t)uvS
ize.fWidth) { |
| 205 return false; | 206 return false; |
| 206 } | 207 } |
| 207 for (int j = 0; j < uvSize.fHeight; ++j) { | 208 for (int j = 0; j < uvSize.fHeight; ++j) { |
| 208 for (int i = 0; i < uvSize.fWidth; ++i) { | 209 for (int i = 0; i < uvSize.fWidth; ++i) { |
| 209 // These writes could surely be made more efficient. | 210 // These writes could surely be made more efficient. |
| 210 uint32_t u = GrColorUnpackR(tempUV.get()[j * uvSize.fWid
th + i]); | 211 uint32_t u = GrColorUnpackR(tempUV.get()[j * uvSize.fWid
th + i]); |
| 211 uint32_t v = GrColorUnpackG(tempUV.get()[j * uvSize.fWid
th + i]); | 212 uint32_t v = GrColorUnpackG(tempUV.get()[j * uvSize.fWid
th + i]); |
| 212 uint8_t* uLoc = ((uint8_t*)planes[1]) + j * uRowBytes +
i; | 213 uint8_t* uLoc = ((uint8_t*)planes[1]) + j * uRowBytes +
i; |
| 213 uint8_t* vLoc = ((uint8_t*)planes[2]) + j * vRowBytes +
i; | 214 uint8_t* vLoc = ((uint8_t*)planes[2]) + j * vRowBytes +
i; |
| 214 *uLoc = u; | 215 *uLoc = u; |
| 215 *vLoc = v; | 216 *vLoc = v; |
| 216 } | 217 } |
| 217 } | 218 } |
| 218 return true; | 219 return true; |
| 219 } else { | 220 } else { |
| 220 SkASSERT(uRenderTargetContext && vRenderTargetContext); | 221 SkASSERT(uRenderTargetContext && vRenderTargetContext); |
| 221 sk_sp<GrTexture> tex(uRenderTargetContext->asTexture()); | 222 sk_sp<GrTextureProxy> tex(uRenderTargetContext->asDeferredTextur
e()); |
| 222 SkASSERT(tex); | 223 SkASSERT(tex); |
| 223 if (!tex->readPixels(0, 0, sizes[1].fWidth, sizes[1].fHeight, | 224 if (!tex->readPixels(0, 0, sizes[1].fWidth, sizes[1].fHeight, |
| 224 kAlpha_8_GrPixelConfig, planes[1], rowBytes
[1])) { | 225 kAlpha_8_GrPixelConfig, planes[1], rowBytes
[1])) { |
| 225 return false; | 226 return false; |
| 226 } | 227 } |
| 227 tex = vRenderTargetContext->asTexture(); | 228 tex = sk_ref_sp(vRenderTargetContext->asDeferredTexture()); |
| 228 SkASSERT(tex); | 229 SkASSERT(tex); |
| 229 if (!tex->readPixels(0, 0, sizes[2].fWidth, sizes[2].fHeight, | 230 if (!tex->readPixels(0, 0, sizes[2].fWidth, sizes[2].fHeight, |
| 230 kAlpha_8_GrPixelConfig, planes[2], rowBytes
[2])) { | 231 kAlpha_8_GrPixelConfig, planes[2], rowBytes
[2])) { |
| 231 return false; | 232 return false; |
| 232 } | 233 } |
| 233 return true; | 234 return true; |
| 234 } | 235 } |
| 235 } | 236 } |
| 236 } | 237 } |
| 237 return false; | 238 return false; |
| 238 } | 239 } |
| OLD | NEW |