blob: cea0f401d1b94bc7333b04bca8f34a87e14ecbf2 [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"
Brian Salomoneebe7352020-12-09 16:37:04 -050012#include "include/gpu/GrRecordingContext.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 Phillipsb0e93a22017-08-29 08:26:54 -040051 GrBackendTextureImageGenerator(const SkImageInfo& info, GrTexture*, GrSurfaceOrigin,
Greg Daniel301015c2019-11-18 14:06:46 -050052 uint32_t owningContextID, std::unique_ptr<GrSemaphore>,
Brian Osman13dddce2017-05-09 13:19:50 -040053 const GrBackendTexture&);
54
55 static void ReleaseRefHelper_TextureReleaseProc(void* ctx);
56
Mike Klein408ef212018-10-30 15:23:00 +000057 class RefHelper : public SkNVRefCnt<RefHelper> {
Brian Osman13dddce2017-05-09 13:19:50 -040058 public:
Greg Daniel301015c2019-11-18 14:06:46 -050059 RefHelper(GrTexture*, uint32_t owningContextID, std::unique_ptr<GrSemaphore>);
Brian Osman13dddce2017-05-09 13:19:50 -040060
61 ~RefHelper();
62
Greg Daniel301015c2019-11-18 14:06:46 -050063 GrTexture* fOriginalTexture;
64 uint32_t fOwningContextID;
Brian Osman13dddce2017-05-09 13:19:50 -040065
Brian Salomonb916b7b2019-04-01 13:34:34 -040066 // We use this key so that we don't rewrap the GrBackendTexture in a GrTexture for each
67 // proxy created from this generator for a particular borrowing context.
Greg Daniel301015c2019-11-18 14:06:46 -050068 GrUniqueKey fBorrowedTextureKey;
Brian Salomonb916b7b2019-04-01 13:34:34 -040069 // There is no ref associated with this pointer. We rely on our atomic bookkeeping with the
70 // context ID to know when this pointer is valid and safe to use. This is used to make sure
71 // all uses of the wrapped texture are finished on the borrowing context before we open
72 // this back up to other contexts. In general a ref to this release proc is owned by all
73 // proxies and gpu uses of the backend texture.
Greg Daniel301015c2019-11-18 14:06:46 -050074 GrRefCntedCallback* fBorrowingContextReleaseProc;
75 uint32_t fBorrowingContextID;
76
77 std::unique_ptr<GrSemaphore> fSemaphore;
Brian Osman13dddce2017-05-09 13:19:50 -040078 };
79
Greg Daniel301015c2019-11-18 14:06:46 -050080 RefHelper* fRefHelper;
Greg Danielabba9982018-02-01 10:07:57 -050081 // This Mutex is used to guard the borrowing of the texture to one GrContext at a time as well
82 // as the creation of the fBorrowingContextReleaseProc. The latter happening if two threads with
83 // the same consuming GrContext try to generate a texture at the same time.
Greg Daniel301015c2019-11-18 14:06:46 -050084 SkMutex fBorrowingMutex;
Brian Osman13dddce2017-05-09 13:19:50 -040085
Greg Daniel301015c2019-11-18 14:06:46 -050086 GrBackendTexture fBackendTexture;
87 GrSurfaceOrigin fSurfaceOrigin;
Brian Osman13dddce2017-05-09 13:19:50 -040088
John Stiles7571f9e2020-09-02 22:42:33 -040089 using INHERITED = SkImageGenerator;
Brian Osman13dddce2017-05-09 13:19:50 -040090};
91#endif // GrBackendTextureImageGenerator_DEFINED