blob: 4519e0acc6b0a3f13bb8d1a5fba06d03d252e258 [file] [log] [blame]
Brian Salomon7ac9b5f2020-06-26 09:09:15 -04001/*
2 * Copyright 2020 Google LLC
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/BackendTextureImageFactory.h"
9
10#include "include/core/SkImage.h"
11#include "include/core/SkPixmap.h"
12#include "include/gpu/GrBackendSurface.h"
13#include "include/gpu/GrContext.h"
14#include "src/core/SkAutoPixmapStorage.h"
15
16namespace {
17class ManagedBackendTexture : public SkNVRefCnt<ManagedBackendTexture> {
18public:
19 ~ManagedBackendTexture() {
20 if (fContext && fTexture.isValid()) {
21 fContext->submit(true);
22 fContext->deleteBackendTexture(fTexture);
23 }
24 }
25
26 static void Proc(void* context) { static_cast<ManagedBackendTexture*>(context)->unref(); }
27
28 template <typename... Args>
29 static sk_sp<ManagedBackendTexture> Make(GrContext* context, Args&&... args) {
30 sk_sp<ManagedBackendTexture> mbet(new ManagedBackendTexture);
31 mbet->fContext = context;
32 mbet->fTexture = context->createBackendTexture(std::forward<Args>(args)...,
33 Proc,
34 mbet->refAndPassAsContext());
35 return mbet;
36 }
37
38 const GrBackendTexture& texture() { return fTexture; }
39
40 void* refAndPassAsContext() {
41 this->ref();
42 return static_cast<void*>(this);
43 }
44
45private:
46 ManagedBackendTexture() = default;
47 GrContext* fContext = nullptr;
48 GrBackendTexture fTexture;
49};
50} // namespace
51
52namespace sk_gpu_test {
53sk_sp<SkImage> MakeBackendTextureImage(GrContext* context,
54 const SkPixmap& pixmap,
55 GrRenderable renderable,
56 GrSurfaceOrigin origin) {
57 const SkPixmap* src = &pixmap;
58 SkAutoPixmapStorage temp;
59 if (origin == kBottomLeft_GrSurfaceOrigin) {
60 temp.alloc(src->info());
61 auto s = static_cast<const char*>(src->addr(0, pixmap.height() - 1));
62 auto d = static_cast<char*>(temp.writable_addr(0, 0));
63 for (int y = 0; y < temp.height(); ++y, s -= pixmap.rowBytes(), d += temp.rowBytes()) {
64 std::copy_n(s, temp.info().minRowBytes(), d);
65 }
66 src = &temp;
67 }
68 auto mbet = ManagedBackendTexture::Make(context, src, 1, renderable, GrProtected::kNo);
69 auto image = SkImage::MakeFromTexture(context, mbet->texture(), origin, src->colorType(),
70 src->alphaType(), src->refColorSpace(),
71 ManagedBackendTexture::Proc, mbet->refAndPassAsContext());
72 // We currently have an issue where depending on how MakeFromTexture fails it may not
73 // call the release proc (to be fixed soon, crbug.com/1097484). For now we use this hack
74 // to see if it failed without calling Proc.
75 if (!image) {
76 context->submit(true);
77 if (!mbet->unique()) {
78 ManagedBackendTexture::Proc(mbet.get());
79 }
80 }
81 return image;
82}
83} // namespace sk_gpu_test