blob: 72bdc96ea7d12db6e8c483a7b50cea982e044d96 [file] [log] [blame]
Brian Osman13dddce2017-05-09 13:19:50 -04001/*
2 * Copyright 2017 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#ifndef GrBackendTextureImageGenerator_DEFINED
8#define GrBackendTextureImageGenerator_DEFINED
9
Mike Kleinc0bd9f92019-04-23 12:05:21 -050010#include "include/core/SkImageGenerator.h"
11#include "include/gpu/GrBackendSurface.h"
Robert Phillipsd074b622021-03-15 08:49:24 -040012#include "include/gpu/GrDirectContext.h"
Mike Kleinc0bd9f92019-04-23 12:05:21 -050013#include "include/private/GrResourceKey.h"
14#include "include/private/SkMutex.h"
Greg Daniel7c902112020-03-06 13:07:10 -050015#include "src/gpu/GrTexture.h"
Brian Osman13dddce2017-05-09 13:19:50 -040016
17class GrSemaphore;
18
Greg Daniel966db9e2018-01-12 13:15:06 -050019/*
20 * This ImageGenerator is used to wrap a texture in one GrContext and can then be used as a source
Greg Danielabba9982018-02-01 10:07:57 -050021 * in another GrContext. It holds onto a semaphore which the producing GrContext will signal and the
Greg Daniel966db9e2018-01-12 13:15:06 -050022 * consuming GrContext will wait on before using the texture. Only one GrContext can ever be used
23 * as a consumer (this is mostly because Vulkan can't allow multiple things to wait on the same
24 * semaphore).
Greg Danielabba9982018-02-01 10:07:57 -050025 *
26 * In practice, this capability is used by clients to create backend-specific texture resources in
27 * one thread (with, say, GrContext-A) and then ship them over to another GrContext (say,
28 * GrContext-B) which will then use the texture as a source for draws. GrContext-A uses the
29 * semaphore to notify GrContext-B when the shared texture is ready to use.
Greg Daniel966db9e2018-01-12 13:15:06 -050030 */
Brian Osman13dddce2017-05-09 13:19:50 -040031class GrBackendTextureImageGenerator : public SkImageGenerator {
32public:
Robert Phillipsb0e93a22017-08-29 08:26:54 -040033 static std::unique_ptr<SkImageGenerator> Make(sk_sp<GrTexture>, GrSurfaceOrigin,
Greg Daniel301015c2019-11-18 14:06:46 -050034 std::unique_ptr<GrSemaphore>, SkColorType,
Brian Osman13dddce2017-05-09 13:19:50 -040035 SkAlphaType, sk_sp<SkColorSpace>);
36
Stan Iliev7e910df2017-06-02 10:29:21 -040037 ~GrBackendTextureImageGenerator() override;
Brian Osman13dddce2017-05-09 13:19:50 -040038
39protected:
Robert Phillips4a3ebc22020-07-10 11:27:43 -040040 bool onIsValid(GrRecordingContext* context) const override {
41 if (context && context->abandoned()) {
42 return false;
43 }
44 return true;
45 }
Brian Osman13dddce2017-05-09 13:19:50 -040046
Brian Salomonecbb0fb2020-02-28 18:07:32 -050047 GrSurfaceProxyView onGenerateTexture(GrRecordingContext*, const SkImageInfo&, const SkIPoint&,
Brian Salomon7e67dca2020-07-21 09:27:25 -040048 GrMipmapped mipMapped, GrImageTexGenPolicy) override;
Brian Osman13dddce2017-05-09 13:19:50 -040049
50private:
Robert Phillipsd074b622021-03-15 08:49:24 -040051 GrBackendTextureImageGenerator(const SkImageInfo& info,
52 GrTexture*,
53 GrSurfaceOrigin,
54 GrDirectContext::DirectContextID owningContextID,
55 std::unique_ptr<GrSemaphore>,
Brian Osman13dddce2017-05-09 13:19:50 -040056 const GrBackendTexture&);
57
58 static void ReleaseRefHelper_TextureReleaseProc(void* ctx);
59
Mike Klein408ef212018-10-30 15:23:00 +000060 class RefHelper : public SkNVRefCnt<RefHelper> {
Brian Osman13dddce2017-05-09 13:19:50 -040061 public:
Robert Phillipsd074b622021-03-15 08:49:24 -040062 RefHelper(GrTexture*,
63 GrDirectContext::DirectContextID owningContextID,
64 std::unique_ptr<GrSemaphore>);
Brian Osman13dddce2017-05-09 13:19:50 -040065
66 ~RefHelper();
67
Robert Phillipsd074b622021-03-15 08:49:24 -040068 GrTexture* fOriginalTexture;
69 GrDirectContext::DirectContextID fOwningContextID;
Brian Osman13dddce2017-05-09 13:19:50 -040070
Brian Salomonb916b7b2019-04-01 13:34:34 -040071 // We use this key so that we don't rewrap the GrBackendTexture in a GrTexture for each
72 // proxy created from this generator for a particular borrowing context.
Robert Phillipsd074b622021-03-15 08:49:24 -040073 GrUniqueKey fBorrowedTextureKey;
Brian Salomonb916b7b2019-04-01 13:34:34 -040074 // There is no ref associated with this pointer. We rely on our atomic bookkeeping with the
75 // context ID to know when this pointer is valid and safe to use. This is used to make sure
76 // all uses of the wrapped texture are finished on the borrowing context before we open
77 // this back up to other contexts. In general a ref to this release proc is owned by all
78 // proxies and gpu uses of the backend texture.
Robert Phillipsd074b622021-03-15 08:49:24 -040079 GrRefCntedCallback* fBorrowingContextReleaseProc;
80 GrDirectContext::DirectContextID fBorrowingContextID;
Greg Daniel301015c2019-11-18 14:06:46 -050081
Robert Phillipsd074b622021-03-15 08:49:24 -040082 std::unique_ptr<GrSemaphore> fSemaphore;
Brian Osman13dddce2017-05-09 13:19:50 -040083 };
84
Greg Daniel301015c2019-11-18 14:06:46 -050085 RefHelper* fRefHelper;
Greg Danielabba9982018-02-01 10:07:57 -050086 // This Mutex is used to guard the borrowing of the texture to one GrContext at a time as well
87 // as the creation of the fBorrowingContextReleaseProc. The latter happening if two threads with
88 // the same consuming GrContext try to generate a texture at the same time.
Greg Daniel301015c2019-11-18 14:06:46 -050089 SkMutex fBorrowingMutex;
Brian Osman13dddce2017-05-09 13:19:50 -040090
Greg Daniel301015c2019-11-18 14:06:46 -050091 GrBackendTexture fBackendTexture;
92 GrSurfaceOrigin fSurfaceOrigin;
Brian Osman13dddce2017-05-09 13:19:50 -040093
John Stiles7571f9e2020-09-02 22:42:33 -040094 using INHERITED = SkImageGenerator;
Brian Osman13dddce2017-05-09 13:19:50 -040095};
96#endif // GrBackendTextureImageGenerator_DEFINED