blob: 6f4ec4f55b5f8981b80dc4e227d0d5eda3435233 [file] [log] [blame]
Robert Phillips96601082018-05-29 16:13:26 -04001/*
2 * Copyright 2018 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#ifndef DDLTileHelper_DEFINED
9#define DDLTileHelper_DEFINED
10
Mike Kleinc0bd9f92019-04-23 12:05:21 -050011#include "include/core/SkRect.h"
12#include "include/core/SkRefCnt.h"
Brian Osmana5842bc2021-05-11 13:41:46 -040013#include "include/core/SkSpan.h"
Kevin Lubick46572b42023-01-18 13:11:06 -050014#include "include/private/base/SkTemplates.h"
Kevin Lubick0bff57e2023-06-09 14:29:17 -040015#include "include/private/chromium/GrDeferredDisplayList.h"
16#include "include/private/chromium/GrSurfaceCharacterization.h"
Robert Phillips96601082018-05-29 16:13:26 -040017
Robert Phillips96601082018-05-29 16:13:26 -040018class DDLPromiseImageHelper;
Robert Phillips11c67672020-04-23 15:10:03 -040019class PromiseImageCallbackContext;
Robert Phillips96601082018-05-29 16:13:26 -040020class SkCanvas;
21class SkData;
Kevin Lubick0bff57e2023-06-09 14:29:17 -040022class GrDeferredDisplayListRecorder;
Kevin Lubick321734e2023-03-14 10:46:56 -040023class SkImage;
Robert Phillips96601082018-05-29 16:13:26 -040024class SkPicture;
25class SkSurface;
Kevin Lubick0bff57e2023-06-09 14:29:17 -040026class GrSurfaceCharacterization;
Robert Phillips1a578572020-07-13 13:17:09 -040027class SkTaskGroup;
Robert Phillips96601082018-05-29 16:13:26 -040028
29class DDLTileHelper {
30public:
Robert Phillipsa865a3a2020-02-14 10:49:39 -050031 // The TileData class encapsulates the information and behavior of a single tile when
32 // rendering with DDLs.
Robert Phillips96601082018-05-29 16:13:26 -040033 class TileData {
34 public:
Robert Phillipscd1e3972021-02-22 17:24:22 -050035 TileData();
Robert Phillipsa865a3a2020-02-14 10:49:39 -050036 ~TileData();
Robert Phillips96601082018-05-29 16:13:26 -040037
Robert Phillips559f9c12021-01-11 12:29:20 -050038 bool initialized() const { return fID != -1; }
39
Robert Phillips19f466d2020-02-26 10:27:07 -050040 void init(int id,
Robert Phillipsd5f3c982020-07-07 13:18:47 -040041 GrDirectContext*,
Kevin Lubick0bff57e2023-06-09 14:29:17 -040042 const GrSurfaceCharacterization& dstChar,
Robert Phillips0c088492020-11-10 08:30:50 -050043 const SkIRect& clip,
44 const SkIRect& paddingOutsets);
Robert Phillipsa865a3a2020-02-14 10:49:39 -050045
Robert Phillipsa865a3a2020-02-14 10:49:39 -050046 // Create the DDL for this tile (i.e., fill in 'fDisplayList').
Adlai Holler55aaefe2021-03-03 16:12:56 -070047 void createDDL(const SkPicture*);
Robert Phillips96601082018-05-29 16:13:26 -040048
Robert Phillips5dbcca52020-05-29 10:41:33 -040049 void dropDDL() { fDisplayList.reset(); }
50
Robert Phillips6eb5cb92020-03-05 12:52:45 -050051 // Precompile all the programs required to draw this tile's DDL
Robert Phillipsd5f3c982020-07-07 13:18:47 -040052 void precompile(GrDirectContext*);
Robert Phillips6eb5cb92020-03-05 12:52:45 -050053
Robert Phillips24a8e9e2020-03-06 20:26:28 +000054 // Just draw the re-inflated per-tile SKP directly into this tile w/o going through a DDL
55 // first. This is used for determining the overhead of using DDLs (i.e., it replaces
56 // a 'createDDL' and 'draw' pair.
Adlai Holler55aaefe2021-03-03 16:12:56 -070057 void drawSKPDirectly(GrDirectContext*, const SkPicture*);
Robert Phillips24a8e9e2020-03-06 20:26:28 +000058
Robert Phillips11c67672020-04-23 15:10:03 -040059 // Replay the recorded DDL into the tile surface - filling in 'fBackendTexture'.
Robert Phillipsd5f3c982020-07-07 13:18:47 -040060 void draw(GrDirectContext*);
Robert Phillips96601082018-05-29 16:13:26 -040061
Robert Phillips96601082018-05-29 16:13:26 -040062 void reset();
63
Robert Phillipsa865a3a2020-02-14 10:49:39 -050064 int id() const { return fID; }
Robert Phillips11c67672020-04-23 15:10:03 -040065 SkIRect clipRect() const { return fClip; }
Robert Phillips0c088492020-11-10 08:30:50 -050066 SkISize paddedRectSize() const {
67 return { fClip.width() + fPaddingOutsets.fLeft + fPaddingOutsets.fRight,
68 fClip.height() + fPaddingOutsets.fTop + fPaddingOutsets.fBottom };
69 }
70 SkIVector padOffset() const { return { fPaddingOutsets.fLeft, fPaddingOutsets.fTop }; }
Robert Phillipsa865a3a2020-02-14 10:49:39 -050071
Kevin Lubick0bff57e2023-06-09 14:29:17 -040072 GrDeferredDisplayList* ddl() { return fDisplayList.get(); }
Robert Phillips7b0ed552020-02-20 12:45:19 -050073
Adlai Holler55aaefe2021-03-03 16:12:56 -070074 sk_sp<SkImage> makePromiseImageForDst(sk_sp<GrContextThreadSafeProxy>);
Robert Phillips11c67672020-04-23 15:10:03 -040075 void dropCallbackContext() { fCallbackContext.reset(); }
76
Robert Phillipsd5f3c982020-07-07 13:18:47 -040077 static void CreateBackendTexture(GrDirectContext*, TileData*);
78 static void DeleteBackendTexture(GrDirectContext*, TileData*);
Robert Phillips8472a3d2020-04-16 16:27:45 -040079
Robert Phillips96601082018-05-29 16:13:26 -040080 private:
Adlai Hollerb2705682020-10-20 10:11:53 -040081 sk_sp<SkSurface> makeWrappedTileDest(GrRecordingContext* context);
Robert Phillips8472a3d2020-04-16 16:27:45 -040082
Robert Phillips11c67672020-04-23 15:10:03 -040083 sk_sp<PromiseImageCallbackContext> refCallbackContext() { return fCallbackContext; }
84
Robert Phillipsa865a3a2020-02-14 10:49:39 -050085 int fID = -1;
Robert Phillips11c67672020-04-23 15:10:03 -040086 SkIRect fClip; // in the device space of the final SkSurface
Robert Phillips0c088492020-11-10 08:30:50 -050087 SkIRect fPaddingOutsets; // random padding for the output surface
Kevin Lubick0bff57e2023-06-09 14:29:17 -040088 GrSurfaceCharacterization fPlaybackChar; // characterization for the tile's dst surface
Robert Phillipsa865a3a2020-02-14 10:49:39 -050089
Kevin Lubickeb981252023-06-13 07:51:26 -040090 // The callback context holds (via its GrPromiseImageTexture) the backend texture
Robert Phillips11c67672020-04-23 15:10:03 -040091 // that is both wrapped in 'fTileSurface' and backs this tile's promise image
92 // (i.e., the one returned by 'makePromiseImage').
93 sk_sp<PromiseImageCallbackContext> fCallbackContext;
94 // 'fTileSurface' wraps the backend texture in 'fCallbackContext' and must exist until
95 // after 'fDisplayList' has been flushed (bc it owns the proxy the DDL's destination
96 // trampoline points at).
97 // TODO: fix the ref-order so we don't need 'fTileSurface' here
Adlai Hollerf19bbb52020-06-29 10:00:08 -040098 sk_sp<SkSurface> fTileSurface;
Robert Phillips11c67672020-04-23 15:10:03 -040099
Kevin Lubick0bff57e2023-06-09 14:29:17 -0400100 sk_sp<GrDeferredDisplayList> fDisplayList;
Robert Phillips96601082018-05-29 16:13:26 -0400101 };
102
Robert Phillipsd5f3c982020-07-07 13:18:47 -0400103 DDLTileHelper(GrDirectContext*,
Kevin Lubick0bff57e2023-06-09 14:29:17 -0400104 const GrSurfaceCharacterization& dstChar,
Robert Phillipsa865a3a2020-02-14 10:49:39 -0500105 const SkIRect& viewport,
Robert Phillips96f6d9a2021-02-26 10:41:06 -0500106 int numXDivisions, int numYDivisions,
Robert Phillips0c088492020-11-10 08:30:50 -0500107 bool addRandomPaddingToDst);
Robert Phillips96601082018-05-29 16:13:26 -0400108
Robert Phillipsa865a3a2020-02-14 10:49:39 -0500109 void kickOffThreadedWork(SkTaskGroup* recordingTaskGroup,
110 SkTaskGroup* gpuTaskGroup,
Robert Phillips0d8722c2021-03-29 13:29:40 -0400111 GrDirectContext*,
112 SkPicture*);
Robert Phillipsa865a3a2020-02-14 10:49:39 -0500113
Robert Phillips0d8722c2021-03-29 13:29:40 -0400114 void createDDLsInParallel(SkPicture*);
Robert Phillips96601082018-05-29 16:13:26 -0400115
Robert Phillips11c67672020-04-23 15:10:03 -0400116 // Create the DDL that will compose all the tile images into a final result.
117 void createComposeDDL();
Kevin Lubick0bff57e2023-06-09 14:29:17 -0400118 const sk_sp<GrDeferredDisplayList>& composeDDL() const { return fComposeDDL; }
Robert Phillips11c67672020-04-23 15:10:03 -0400119
Robert Phillips24a8e9e2020-03-06 20:26:28 +0000120 // For each tile, create its DDL and then draw it - all on a single thread. This is to allow
121 // comparison w/ just drawing the SKP directly (i.e., drawAllTilesDirectly). The
122 // DDL creations and draws are interleaved to prevent starvation of the GPU.
123 // Note: this is somewhat of a misuse/pessimistic-use of DDLs since they are supposed to
124 // be created on a separate thread.
Robert Phillips0d8722c2021-03-29 13:29:40 -0400125 void interleaveDDLCreationAndDraw(GrDirectContext*, SkPicture*);
Robert Phillips24a8e9e2020-03-06 20:26:28 +0000126
127 // This draws all the per-tile SKPs directly into all of the tiles w/o converting them to
128 // DDLs first - all on a single thread.
Robert Phillips0d8722c2021-03-29 13:29:40 -0400129 void drawAllTilesDirectly(GrDirectContext*, SkPicture*);
Robert Phillips24a8e9e2020-03-06 20:26:28 +0000130
Robert Phillips11c67672020-04-23 15:10:03 -0400131 void dropCallbackContexts();
Robert Phillips96601082018-05-29 16:13:26 -0400132 void resetAllTiles();
133
Robert Phillips96f6d9a2021-02-26 10:41:06 -0500134 int numTiles() const { return fNumXDivisions * fNumYDivisions; }
Robert Phillipsa865a3a2020-02-14 10:49:39 -0500135
Robert Phillipsd5f3c982020-07-07 13:18:47 -0400136 void createBackendTextures(SkTaskGroup*, GrDirectContext*);
137 void deleteBackendTextures(SkTaskGroup*, GrDirectContext*);
Robert Phillips8472a3d2020-04-16 16:27:45 -0400138
Robert Phillips96601082018-05-29 16:13:26 -0400139private:
Robert Phillips96f6d9a2021-02-26 10:41:06 -0500140 int fNumXDivisions; // number of tiles horizontally
141 int fNumYDivisions; // number of tiles vertically
Herb Derby3b3bcf02023-01-17 15:12:15 -0500142 skia_private::AutoTArray<TileData> fTiles; // 'fNumXDivisions' x
143 // 'fNumYDivisions'
Robert Phillips11c67672020-04-23 15:10:03 -0400144
Kevin Lubick0bff57e2023-06-09 14:29:17 -0400145 sk_sp<GrDeferredDisplayList> fComposeDDL;
Robert Phillips11c67672020-04-23 15:10:03 -0400146
Kevin Lubick0bff57e2023-06-09 14:29:17 -0400147 const GrSurfaceCharacterization fDstCharacterization;
Robert Phillips96601082018-05-29 16:13:26 -0400148};
149
150#endif