• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
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 
8 #include "tools/gpu/YUVUtils.h"
9 
10 #include "include/core/SkData.h"
11 #include "include/gpu/GrContext.h"
12 #include "src/codec/SkCodecImageGenerator.h"
13 #include "src/gpu/GrContextPriv.h"
14 
15 namespace sk_gpu_test {
16 
Make(sk_sp<SkData> data)17 std::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 
refImage(GrContext * context)26 sk_sp<SkImage> LazyYUVImage::refImage(GrContext* context) {
27     if (this->ensureYUVImage(context)) {
28         return fYUVImage;
29     } else {
30         return nullptr;
31     }
32 }
33 
getImage(GrContext * context)34 const SkImage* LazyYUVImage::getImage(GrContext* context) {
35     if (this->ensureYUVImage(context)) {
36         return fYUVImage.get();
37     } else {
38         return nullptr;
39     }
40 }
41 
reset(sk_sp<SkData> data)42 bool 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 
ensureYUVImage(GrContext * context)74 bool 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
89