blob: 0fe4ef6d96b3e4a7409e23fb5b4168719c330826 [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"
12#include "include/private/GrResourceKey.h"
13#include "include/private/SkMutex.h"
Greg Daniel7c902112020-03-06 13:07:10 -050014#include "src/gpu/GrTexture.h"
Brian Osman13dddce2017-05-09 13:19:50 -040015
16class GrSemaphore;
17
Greg Daniel966db9e2018-01-12 13:15:06 -050018/*
19 * 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 -050020 * in another GrContext. It holds onto a semaphore which the producing GrContext will signal and the
Greg Daniel966db9e2018-01-12 13:15:06 -050021 * consuming GrContext will wait on before using the texture. Only one GrContext can ever be used
22 * as a consumer (this is mostly because Vulkan can't allow multiple things to wait on the same
23 * semaphore).
Greg Danielabba9982018-02-01 10:07:57 -050024 *
25 * In practice, this capability is used by clients to create backend-specific texture resources in
26 * one thread (with, say, GrContext-A) and then ship them over to another GrContext (say,
27 * GrContext-B) which will then use the texture as a source for draws. GrContext-A uses the
28 * semaphore to notify GrContext-B when the shared texture is ready to use.
Greg Daniel966db9e2018-01-12 13:15:06 -050029 */
Brian Osman13dddce2017-05-09 13:19:50 -040030class GrBackendTextureImageGenerator : public SkImageGenerator {
31public:
Robert Phillipsb0e93a22017-08-29 08:26:54 -040032 static std::unique_ptr<SkImageGenerator> Make(sk_sp<GrTexture>, GrSurfaceOrigin,
Greg Daniel301015c2019-11-18 14:06:46 -050033 std::unique_ptr<GrSemaphore>, SkColorType,
Brian Osman13dddce2017-05-09 13:19:50 -040034 SkAlphaType, sk_sp<SkColorSpace>);
35
Stan Iliev7e910df2017-06-02 10:29:21 -040036 ~GrBackendTextureImageGenerator() override;
Brian Osman13dddce2017-05-09 13:19:50 -040037
38protected:
Robert Phillips4a3ebc22020-07-10 11:27:43 -040039 bool onIsValid(GrRecordingContext* context) const override {
40 if (context && context->abandoned()) {
41 return false;
42 }
43 return true;
44 }
Brian Osman13dddce2017-05-09 13:19:50 -040045
Brian Salomonecbb0fb2020-02-28 18:07:32 -050046 GrSurfaceProxyView onGenerateTexture(GrRecordingContext*, const SkImageInfo&, const SkIPoint&,
Brian Salomon7e67dca2020-07-21 09:27:25 -040047 GrMipmapped mipMapped, GrImageTexGenPolicy) override;
Brian Osman13dddce2017-05-09 13:19:50 -040048
49private:
Robert Phillipsb0e93a22017-08-29 08:26:54 -040050 GrBackendTextureImageGenerator(const SkImageInfo& info, GrTexture*, GrSurfaceOrigin,
Greg Daniel301015c2019-11-18 14:06:46 -050051 uint32_t owningContextID, std::unique_ptr<GrSemaphore>,
Brian Osman13dddce2017-05-09 13:19:50 -040052 const GrBackendTexture&);
53
54 static void ReleaseRefHelper_TextureReleaseProc(void* ctx);
55
Mike Klein408ef212018-10-30 15:23:00 +000056 class RefHelper : public SkNVRefCnt<RefHelper> {
Brian Osman13dddce2017-05-09 13:19:50 -040057 public:
Greg Daniel301015c2019-11-18 14:06:46 -050058 RefHelper(GrTexture*, uint32_t owningContextID, std::unique_ptr<GrSemaphore>);
Brian Osman13dddce2017-05-09 13:19:50 -040059
60 ~RefHelper();
61
Greg Daniel301015c2019-11-18 14:06:46 -050062 GrTexture* fOriginalTexture;
63 uint32_t fOwningContextID;
Brian Osman13dddce2017-05-09 13:19:50 -040064
Brian Salomonb916b7b2019-04-01 13:34:34 -040065 // We use this key so that we don't rewrap the GrBackendTexture in a GrTexture for each
66 // proxy created from this generator for a particular borrowing context.
Greg Daniel301015c2019-11-18 14:06:46 -050067 GrUniqueKey fBorrowedTextureKey;
Brian Salomonb916b7b2019-04-01 13:34:34 -040068 // There is no ref associated with this pointer. We rely on our atomic bookkeeping with the
69 // context ID to know when this pointer is valid and safe to use. This is used to make sure
70 // all uses of the wrapped texture are finished on the borrowing context before we open
71 // this back up to other contexts. In general a ref to this release proc is owned by all
72 // proxies and gpu uses of the backend texture.
Greg Daniel301015c2019-11-18 14:06:46 -050073 GrRefCntedCallback* fBorrowingContextReleaseProc;
74 uint32_t fBorrowingContextID;
75
76 std::unique_ptr<GrSemaphore> fSemaphore;
Brian Osman13dddce2017-05-09 13:19:50 -040077 };
78
Greg Daniel301015c2019-11-18 14:06:46 -050079 RefHelper* fRefHelper;
Greg Danielabba9982018-02-01 10:07:57 -050080 // This Mutex is used to guard the borrowing of the texture to one GrContext at a time as well
81 // as the creation of the fBorrowingContextReleaseProc. The latter happening if two threads with
82 // the same consuming GrContext try to generate a texture at the same time.
Greg Daniel301015c2019-11-18 14:06:46 -050083 SkMutex fBorrowingMutex;
Brian Osman13dddce2017-05-09 13:19:50 -040084
Greg Daniel301015c2019-11-18 14:06:46 -050085 GrBackendTexture fBackendTexture;
86 GrSurfaceOrigin fSurfaceOrigin;
Brian Osman13dddce2017-05-09 13:19:50 -040087
88 typedef SkImageGenerator INHERITED;
89};
90#endif // GrBackendTextureImageGenerator_DEFINED