blob: eb4ca2c3d124beea93ab85b6f9498256e718d12b [file] [log] [blame]
Michael Ludwigd9958f82019-03-21 13:08:36 -04001/*
2 * Copyright 2019 Google Inc.
3 *
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
6 */
7
Mike Kleinc0bd9f92019-04-23 12:05:21 -05008#include "tools/gpu/YUVUtils.h"
Michael Ludwigd9958f82019-03-21 13:08:36 -04009
Mike Kleinc0bd9f92019-04-23 12:05:21 -050010#include "include/core/SkData.h"
11#include "include/gpu/GrContext.h"
12#include "src/codec/SkCodecImageGenerator.h"
13#include "src/gpu/GrContextPriv.h"
Michael Ludwigd9958f82019-03-21 13:08:36 -040014
15namespace sk_gpu_test {
16
17std::unique_ptr<LazyYUVImage> LazyYUVImage::Make(sk_sp<SkData> data) {
18 std::unique_ptr<LazyYUVImage> image(new LazyYUVImage());
19 if (image->reset(std::move(data))) {
20 return image;
21 } else {
22 return nullptr;
23 }
24}
25
26sk_sp<SkImage> LazyYUVImage::refImage(GrContext* context) {
27 if (this->ensureYUVImage(context)) {
28 return fYUVImage;
29 } else {
30 return nullptr;
31 }
32}
33
34const SkImage* LazyYUVImage::getImage(GrContext* context) {
35 if (this->ensureYUVImage(context)) {
36 return fYUVImage.get();
37 } else {
38 return nullptr;
39 }
40}
41
42bool LazyYUVImage::reset(sk_sp<SkData> data) {
43 auto codec = SkCodecImageGenerator::MakeFromEncodedCodec(data);
44 if (!codec) {
45 return false;
46 }
47
48 if (!codec->queryYUVA8(&fSizeInfo, fComponents, &fColorSpace)) {
49 return false;
50 }
51
52 fPlaneData.reset(fSizeInfo.computeTotalBytes());
53 void* planes[SkYUVASizeInfo::kMaxCount];
54 fSizeInfo.computePlanes(fPlaneData.get(), planes);
55 if (!codec->getYUVA8Planes(fSizeInfo, fComponents, planes)) {
56 return false;
57 }
58
59 for (int i = 0; i < SkYUVASizeInfo::kMaxCount; ++i) {
60 if (fSizeInfo.fSizes[i].isEmpty()) {
61 fPlanes[i].reset();
62 } else {
63 SkASSERT(planes[i]);
64 auto planeInfo = SkImageInfo::Make(fSizeInfo.fSizes[i].fWidth,
65 fSizeInfo.fSizes[i].fHeight,
66 kGray_8_SkColorType, kOpaque_SkAlphaType, nullptr);
67 fPlanes[i].reset(planeInfo, planes[i], fSizeInfo.fWidthBytes[i]);
68 }
69 }
70 // The SkPixmap data is fully configured now for MakeFromYUVAPixmaps once we get a GrContext
71 return true;
72}
73
74bool LazyYUVImage::ensureYUVImage(GrContext* context) {
75 if (!context) {
76 return false; // Cannot make a YUV image from planes
77 }
78 if (context->priv().contextID() == fOwningContextID) {
79 return fYUVImage != nullptr; // Have already made a YUV image (or tried and failed)
80 }
81 // Must make a new YUV image
82 fYUVImage = SkImage::MakeFromYUVAPixmaps(context, fColorSpace, fPlanes, fComponents,
83 fSizeInfo.fSizes[0], kTopLeft_GrSurfaceOrigin, false, false);
84 fOwningContextID = context->priv().contextID();
85 return fYUVImage != nullptr;
86}
87
88} // namespace sk_gpu_test