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

Unified Diff: src/gpu/GrYUVProvider.cpp

Issue 1315353006: refactor parts of SkGr.cpp for use by SkImages (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: fix header Created 5 years, 3 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 side-by-side diff with in-line comments
Download patch
Index: src/gpu/GrYUVProvider.cpp
diff --git a/src/gpu/GrYUVProvider.cpp b/src/gpu/GrYUVProvider.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..f89b782792749f67899b851468d5c1af8b857b0e
--- /dev/null
+++ b/src/gpu/GrYUVProvider.cpp
@@ -0,0 +1,135 @@
+/*
+ * Copyright 2015 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#include "GrContext.h"
+#include "GrDrawContext.h"
+#include "GrYUVProvider.h"
+#include "effects/GrYUVtoRGBEffect.h"
+
+#include "SkCachedData.h"
+#include "SkRefCnt.h"
+#include "SkResourceCache.h"
+#include "SkYUVPlanesCache.h"
+
+namespace {
+class YUVScoper {
+public:
+ bool init(GrYUVProvider*, SkYUVPlanesCache::Info*, void* planes[3], bool useCache);
+
+private:
+ SkAutoTUnref<SkCachedData> fCachedData;
+ SkAutoMalloc fStorage;
+};
+}
+
+bool YUVScoper::init(GrYUVProvider* provider, SkYUVPlanesCache::Info* yuvInfo, void* planes[3],
+ bool useCache) {
+ if (useCache) {
+ fCachedData.reset(SkYUVPlanesCache::FindAndRef(provider->onGetID(), yuvInfo));
+ }
+
+ if (fCachedData.get()) {
+ planes[0] = (void*)fCachedData->data();
+ planes[1] = (uint8_t*)planes[0] + yuvInfo->fSizeInMemory[0];
+ planes[2] = (uint8_t*)planes[1] + yuvInfo->fSizeInMemory[1];
+ } else {
+ // Fetch yuv plane sizes for memory allocation. Here, width and height can be
+ // rounded up to JPEG block size and be larger than the image's width and height.
+ if (!provider->onGetYUVSizes(yuvInfo->fSize)) {
+ return false;
+ }
+
+ // Allocate the memory for YUV
+ size_t totalSize(0);
robertphillips 2015/09/08 13:34:35 3 -> kPlaneCount ?
reed1 2015/09/08 14:57:22 Done.
+ for (int i = 0; i < 3; ++i) {
+ yuvInfo->fRowBytes[i] = yuvInfo->fSize[i].fWidth;
+ yuvInfo->fSizeInMemory[i] = yuvInfo->fRowBytes[i] * yuvInfo->fSize[i].fHeight;
+ totalSize += yuvInfo->fSizeInMemory[i];
+ }
+ if (useCache) {
+ fCachedData.reset(SkResourceCache::NewCachedData(totalSize));
+ planes[0] = fCachedData->writable_data();
+ } else {
+ fStorage.reset(totalSize);
+ planes[0] = fStorage.get();
+ }
+ planes[1] = (uint8_t*)planes[0] + yuvInfo->fSizeInMemory[0];
+ planes[2] = (uint8_t*)planes[1] + yuvInfo->fSizeInMemory[1];
+
+ // Get the YUV planes and update plane sizes to actual image size
+ if (!provider->onGetYUVPlanes(yuvInfo->fSize, planes, yuvInfo->fRowBytes,
+ &yuvInfo->fColorSpace)) {
+ return false;
+ }
+
+ if (useCache) {
+ // Decoding is done, cache the resulting YUV planes
+ SkYUVPlanesCache::Add(provider->onGetID(), fCachedData, yuvInfo);
+ }
+ }
+ return true;
+}
+
+GrTexture* GrYUVProvider::refAsTexture(GrContext* ctx, const GrSurfaceDesc& desc, bool useCache) {
+ SkYUVPlanesCache::Info yuvInfo;
robertphillips 2015/09/08 13:34:35 3 -> kPlaneCount ?
+ void* planes[3];
+ YUVScoper scoper;
+ if (!scoper.init(this, &yuvInfo, planes, useCache)) {
+ return nullptr;
+ }
+
+ GrSurfaceDesc yuvDesc;
+ yuvDesc.fConfig = kAlpha_8_GrPixelConfig;
+ SkAutoTUnref<GrTexture> yuvTextures[3];
+ for (int i = 0; i < 3; ++i) {
+ yuvDesc.fWidth = yuvInfo.fSize[i].fWidth;
+ yuvDesc.fHeight = yuvInfo.fSize[i].fHeight;
+ bool needsExactTexture =
robertphillips 2015/09/08 13:34:35 This indent seems sub-optimal Also, what is the l
reed1 2015/09/08 14:57:22 Done.
+ (yuvDesc.fWidth != yuvInfo.fSize[0].fWidth) ||
+ (yuvDesc.fHeight != yuvInfo.fSize[0].fHeight);
+ if (needsExactTexture) {
+ yuvTextures[i].reset(ctx->textureProvider()->createTexture(yuvDesc, true));
+ } else {
+ yuvTextures[i].reset(ctx->textureProvider()->createApproxTexture(yuvDesc));
+ }
+ if (!yuvTextures[i] ||
+ !yuvTextures[i]->writePixels(0, 0, yuvDesc.fWidth, yuvDesc.fHeight,
+ yuvDesc.fConfig, planes[i], yuvInfo.fRowBytes[i])) {
+ return nullptr;
+ }
+ }
+
+ GrSurfaceDesc rtDesc = desc;
+ rtDesc.fFlags = rtDesc.fFlags | kRenderTarget_GrSurfaceFlag;
+
+ GrTexture* result = ctx->textureProvider()->createTexture(rtDesc, true, nullptr, 0);
+ if (!result) {
+ return nullptr;
+ }
+
+ GrRenderTarget* renderTarget = result->asRenderTarget();
+ SkASSERT(renderTarget);
+
+ GrPaint paint;
+ SkAutoTUnref<GrFragmentProcessor>
+ yuvToRgbProcessor(GrYUVtoRGBEffect::Create(paint.getProcessorDataManager(), yuvTextures[0],
+ yuvTextures[1], yuvTextures[2],
+ yuvInfo.fSize, yuvInfo.fColorSpace));
+ paint.addColorFragmentProcessor(yuvToRgbProcessor);
+ SkRect r = SkRect::MakeWH(SkIntToScalar(yuvInfo.fSize[0].fWidth),
+ SkIntToScalar(yuvInfo.fSize[0].fHeight));
+
+ SkAutoTUnref<GrDrawContext> drawContext(ctx->drawContext());
+ if (!drawContext) {
robertphillips 2015/09/08 13:34:35 Won't 'result' leak here ?
reed1 2015/09/08 14:57:22 Done.
+ return nullptr;
+ }
+
+ drawContext->drawRect(renderTarget, GrClip::WideOpen(), paint, SkMatrix::I(), r);
+
+ return result;
+}
+

Powered by Google App Engine
This is Rietveld 408576698