blob: b147ad824fe3e5380c92b62ca656a1163d97012a [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
Adlai Holler7580ad42020-06-24 13:45:25 -040011#include "include/core/SkDeferredDisplayList.h"
Mike Kleinc0bd9f92019-04-23 12:05:21 -050012#include "include/core/SkRect.h"
13#include "include/core/SkRefCnt.h"
Brian Osmana5842bc2021-05-11 13:41:46 -040014#include "include/core/SkSpan.h"
Mike Kleinc0bd9f92019-04-23 12:05:21 -050015#include "include/core/SkSurfaceCharacterization.h"
Robert Phillips96601082018-05-29 16:13:26 -040016
Robert Phillips96601082018-05-29 16:13:26 -040017class DDLPromiseImageHelper;
Robert Phillips11c67672020-04-23 15:10:03 -040018class PromiseImageCallbackContext;
Robert Phillips96601082018-05-29 16:13:26 -040019class SkCanvas;
20class SkData;
Robert Phillips11c67672020-04-23 15:10:03 -040021class SkDeferredDisplayListRecorder;
Robert Phillips96601082018-05-29 16:13:26 -040022class SkPicture;
23class SkSurface;
24class SkSurfaceCharacterization;
Robert Phillips1a578572020-07-13 13:17:09 -040025class SkTaskGroup;
Robert Phillips96601082018-05-29 16:13:26 -040026
27class DDLTileHelper {
28public:
Robert Phillipsa865a3a2020-02-14 10:49:39 -050029 // The TileData class encapsulates the information and behavior of a single tile when
30 // rendering with DDLs.
Robert Phillips96601082018-05-29 16:13:26 -040031 class TileData {
32 public:
Robert Phillipscd1e3972021-02-22 17:24:22 -050033 TileData();
Robert Phillipsa865a3a2020-02-14 10:49:39 -050034 ~TileData();
Robert Phillips96601082018-05-29 16:13:26 -040035
Robert Phillips559f9c12021-01-11 12:29:20 -050036 bool initialized() const { return fID != -1; }
37
Robert Phillips19f466d2020-02-26 10:27:07 -050038 void init(int id,
Robert Phillipsd5f3c982020-07-07 13:18:47 -040039 GrDirectContext*,
Robert Phillips19f466d2020-02-26 10:27:07 -050040 const SkSurfaceCharacterization& dstChar,
Robert Phillips0c088492020-11-10 08:30:50 -050041 const SkIRect& clip,
42 const SkIRect& paddingOutsets);
Robert Phillipsa865a3a2020-02-14 10:49:39 -050043
Robert Phillipsa865a3a2020-02-14 10:49:39 -050044 // Create the DDL for this tile (i.e., fill in 'fDisplayList').
Adlai Holler55aaefe2021-03-03 16:12:56 -070045 void createDDL(const SkPicture*);
Robert Phillips96601082018-05-29 16:13:26 -040046
Robert Phillips5dbcca52020-05-29 10:41:33 -040047 void dropDDL() { fDisplayList.reset(); }
48
Robert Phillips6eb5cb92020-03-05 12:52:45 -050049 // Precompile all the programs required to draw this tile's DDL
Robert Phillipsd5f3c982020-07-07 13:18:47 -040050 void precompile(GrDirectContext*);
Robert Phillips6eb5cb92020-03-05 12:52:45 -050051
Robert Phillips24a8e9e2020-03-06 20:26:28 +000052 // Just draw the re-inflated per-tile SKP directly into this tile w/o going through a DDL
53 // first. This is used for determining the overhead of using DDLs (i.e., it replaces
54 // a 'createDDL' and 'draw' pair.
Adlai Holler55aaefe2021-03-03 16:12:56 -070055 void drawSKPDirectly(GrDirectContext*, const SkPicture*);
Robert Phillips24a8e9e2020-03-06 20:26:28 +000056
Robert Phillips11c67672020-04-23 15:10:03 -040057 // Replay the recorded DDL into the tile surface - filling in 'fBackendTexture'.
Robert Phillipsd5f3c982020-07-07 13:18:47 -040058 void draw(GrDirectContext*);
Robert Phillips96601082018-05-29 16:13:26 -040059
Robert Phillips96601082018-05-29 16:13:26 -040060 void reset();
61
Robert Phillipsa865a3a2020-02-14 10:49:39 -050062 int id() const { return fID; }
Robert Phillips11c67672020-04-23 15:10:03 -040063 SkIRect clipRect() const { return fClip; }
Robert Phillips0c088492020-11-10 08:30:50 -050064 SkISize paddedRectSize() const {
65 return { fClip.width() + fPaddingOutsets.fLeft + fPaddingOutsets.fRight,
66 fClip.height() + fPaddingOutsets.fTop + fPaddingOutsets.fBottom };
67 }
68 SkIVector padOffset() const { return { fPaddingOutsets.fLeft, fPaddingOutsets.fTop }; }
Robert Phillipsa865a3a2020-02-14 10:49:39 -050069
Robert Phillips7b0ed552020-02-20 12:45:19 -050070 SkDeferredDisplayList* ddl() { return fDisplayList.get(); }
71
Adlai Holler55aaefe2021-03-03 16:12:56 -070072 sk_sp<SkImage> makePromiseImageForDst(sk_sp<GrContextThreadSafeProxy>);
Robert Phillips11c67672020-04-23 15:10:03 -040073 void dropCallbackContext() { fCallbackContext.reset(); }
74
Robert Phillipsd5f3c982020-07-07 13:18:47 -040075 static void CreateBackendTexture(GrDirectContext*, TileData*);
76 static void DeleteBackendTexture(GrDirectContext*, TileData*);
Robert Phillips8472a3d2020-04-16 16:27:45 -040077
Robert Phillips96601082018-05-29 16:13:26 -040078 private:
Adlai Hollerb2705682020-10-20 10:11:53 -040079 sk_sp<SkSurface> makeWrappedTileDest(GrRecordingContext* context);
Robert Phillips8472a3d2020-04-16 16:27:45 -040080
Robert Phillips11c67672020-04-23 15:10:03 -040081 sk_sp<PromiseImageCallbackContext> refCallbackContext() { return fCallbackContext; }
82
Robert Phillipsa865a3a2020-02-14 10:49:39 -050083 int fID = -1;
Robert Phillips11c67672020-04-23 15:10:03 -040084 SkIRect fClip; // in the device space of the final SkSurface
Robert Phillips0c088492020-11-10 08:30:50 -050085 SkIRect fPaddingOutsets; // random padding for the output surface
Robert Phillipsbc688322020-12-14 11:38:59 -050086 SkSurfaceCharacterization fPlaybackChar; // characterization for the tile's dst surface
Robert Phillipsa865a3a2020-02-14 10:49:39 -050087
Robert Phillips11c67672020-04-23 15:10:03 -040088 // The callback context holds (via its SkPromiseImageTexture) the backend texture
89 // that is both wrapped in 'fTileSurface' and backs this tile's promise image
90 // (i.e., the one returned by 'makePromiseImage').
91 sk_sp<PromiseImageCallbackContext> fCallbackContext;
92 // 'fTileSurface' wraps the backend texture in 'fCallbackContext' and must exist until
93 // after 'fDisplayList' has been flushed (bc it owns the proxy the DDL's destination
94 // trampoline points at).
95 // TODO: fix the ref-order so we don't need 'fTileSurface' here
Adlai Hollerf19bbb52020-06-29 10:00:08 -040096 sk_sp<SkSurface> fTileSurface;
Robert Phillips11c67672020-04-23 15:10:03 -040097
Adlai Hollerf19bbb52020-06-29 10:00:08 -040098 sk_sp<SkDeferredDisplayList> fDisplayList;
Robert Phillips96601082018-05-29 16:13:26 -040099 };
100
Robert Phillipsd5f3c982020-07-07 13:18:47 -0400101 DDLTileHelper(GrDirectContext*,
Robert Phillips19f466d2020-02-26 10:27:07 -0500102 const SkSurfaceCharacterization& dstChar,
Robert Phillipsa865a3a2020-02-14 10:49:39 -0500103 const SkIRect& viewport,
Robert Phillips96f6d9a2021-02-26 10:41:06 -0500104 int numXDivisions, int numYDivisions,
Robert Phillips0c088492020-11-10 08:30:50 -0500105 bool addRandomPaddingToDst);
Robert Phillips96601082018-05-29 16:13:26 -0400106
Robert Phillipsa865a3a2020-02-14 10:49:39 -0500107 void kickOffThreadedWork(SkTaskGroup* recordingTaskGroup,
108 SkTaskGroup* gpuTaskGroup,
Robert Phillips0d8722c2021-03-29 13:29:40 -0400109 GrDirectContext*,
110 SkPicture*);
Robert Phillipsa865a3a2020-02-14 10:49:39 -0500111
Robert Phillips0d8722c2021-03-29 13:29:40 -0400112 void createDDLsInParallel(SkPicture*);
Robert Phillips96601082018-05-29 16:13:26 -0400113
Robert Phillips11c67672020-04-23 15:10:03 -0400114 // Create the DDL that will compose all the tile images into a final result.
115 void createComposeDDL();
Adlai Hollerf19bbb52020-06-29 10:00:08 -0400116 const sk_sp<SkDeferredDisplayList>& composeDDL() const { return fComposeDDL; }
Robert Phillips11c67672020-04-23 15:10:03 -0400117
Robert Phillips24a8e9e2020-03-06 20:26:28 +0000118 // For each tile, create its DDL and then draw it - all on a single thread. This is to allow
119 // comparison w/ just drawing the SKP directly (i.e., drawAllTilesDirectly). The
120 // DDL creations and draws are interleaved to prevent starvation of the GPU.
121 // Note: this is somewhat of a misuse/pessimistic-use of DDLs since they are supposed to
122 // be created on a separate thread.
Robert Phillips0d8722c2021-03-29 13:29:40 -0400123 void interleaveDDLCreationAndDraw(GrDirectContext*, SkPicture*);
Robert Phillips24a8e9e2020-03-06 20:26:28 +0000124
125 // This draws all the per-tile SKPs directly into all of the tiles w/o converting them to
126 // DDLs first - all on a single thread.
Robert Phillips0d8722c2021-03-29 13:29:40 -0400127 void drawAllTilesDirectly(GrDirectContext*, SkPicture*);
Robert Phillips24a8e9e2020-03-06 20:26:28 +0000128
Robert Phillips11c67672020-04-23 15:10:03 -0400129 void dropCallbackContexts();
Robert Phillips96601082018-05-29 16:13:26 -0400130 void resetAllTiles();
131
Robert Phillips96f6d9a2021-02-26 10:41:06 -0500132 int numTiles() const { return fNumXDivisions * fNumYDivisions; }
Robert Phillipsa865a3a2020-02-14 10:49:39 -0500133
Robert Phillipsd5f3c982020-07-07 13:18:47 -0400134 void createBackendTextures(SkTaskGroup*, GrDirectContext*);
135 void deleteBackendTextures(SkTaskGroup*, GrDirectContext*);
Robert Phillips8472a3d2020-04-16 16:27:45 -0400136
Robert Phillips96601082018-05-29 16:13:26 -0400137private:
Robert Phillips96f6d9a2021-02-26 10:41:06 -0500138 int fNumXDivisions; // number of tiles horizontally
139 int fNumYDivisions; // number of tiles vertically
140 SkAutoTArray<TileData> fTiles; // 'fNumXDivisions' x 'fNumYDivisions'
Robert Phillips11c67672020-04-23 15:10:03 -0400141
Adlai Hollerf19bbb52020-06-29 10:00:08 -0400142 sk_sp<SkDeferredDisplayList> fComposeDDL;
Robert Phillips11c67672020-04-23 15:10:03 -0400143
144 const SkSurfaceCharacterization fDstCharacterization;
Robert Phillips96601082018-05-29 16:13:26 -0400145};
146
147#endif