/* * Copyright 2015 Google Inc. * * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ #ifndef GrDrawOpAtlas_DEFINED #define GrDrawOpAtlas_DEFINED #include "include/core/SkRefCnt.h" #include "include/core/SkSize.h" #include "include/gpu/ganesh/GrBackendSurface.h" #include "include/private/base/SkAssert.h" #include "include/private/base/SkDebug.h" #include "src/gpu/AtlasTypes.h" #include "src/gpu/ganesh/GrDeferredUpload.h" #include "src/gpu/ganesh/GrSurfaceProxyView.h" #include <cstddef> #include <cstdint> #include <memory> #include <string> #include <string_view> #include <vector> class GrOnFlushResourceProvider; class GrProxyProvider; class GrResourceProvider; class GrTextureProxy; enum SkColorType : int; /** * This class manages one or more atlas textures on behalf of GrDrawOps. The draw ops that use the * atlas perform texture uploads when preparing their draws during flush. The class provides * facilities for using GrDrawOpUploadToken to detect data hazards. Op's uploads are performed in * "ASAP" mode until it is impossible to add data without overwriting texels read by draws that * have not yet executed on the gpu. At that point, the atlas will attempt to allocate a new * atlas texture (or "page") of the same size, up to a maximum number of textures, and upload * to that texture. If that's not possible, the uploads are performed "inline" between draws. If a * single draw would use enough subimage space to overflow the atlas texture then the atlas will * fail to add a subimage. This gives the op the chance to end the draw and begin a new one. * Additional uploads will then succeed in inline mode. * * When the atlas has multiple pages, new uploads are prioritized to the lower index pages, i.e., * it will try to upload to page 0 before page 1 or 2. To keep the atlas from continually using * excess space, periodic garbage collection is needed to shift data from the higher index pages to * the lower ones, and then eventually remove any pages that are no longer in use. "In use" is * determined by using the GrDrawUploadToken system: After a flush each subarea of the page * is checked to see whether it was used in that flush. If less than a quarter of the plots have * been used recently (within kPlotRecentlyUsedCount iterations) and there are available * plots in lower index pages, the higher index page will be deactivated, and its glyphs will * gradually migrate to other pages via the usual upload system. * * Garbage collection is initiated by the GrDrawOpAtlas's client via the compact() method. One * solution is to make the client a subclass of GrOnFlushCallbackObject, register it with the * GrContext via addOnFlushCallbackObject(), and the client's postFlush() method calls compact() * and passes in the given GrDrawUploadToken. */ class GrDrawOpAtlas { … }; // There are three atlases (A8, 565, ARGB) that are kept in relation with one another. In // general, because A8 is the most frequently used mask format its dimensions are 2x the 565 and // ARGB dimensions, with the constraint that an atlas size will always contain at least one plot. // Since the ARGB atlas takes the most space, its dimensions are used to size the other two atlases. class GrDrawOpAtlasConfig { … }; #endif