| /* | |
| * Copyright 2018 Google Inc. | |
| * | |
| * Use of this source code is governed by a BSD-style license that can be | |
| * found in the LICENSE file. | |
| */ | |
| #ifndef GrDDLTextureStripAtlas_DEFINED | |
| #define GrDDLTextureStripAtlas_DEFINED | |
| #include "GrTextureStripAtlas.h" | |
| #include "SkBitmap.h" | |
| #include "SkTDArray.h" | |
| /** | |
| * The DDL version of the texture strip atlas consolidates individual strips into a larger texture | |
| * until some limit is reached, at which point a new large texture is started. | |
| * This can lead to the same strip being duplicated in VRAM. This can happen if a strip appears once | |
| * early in a rendering (that has, say, a lot of gradients) and then again later in the rendering | |
| * when one of the large textures has been filled. The second, probably more common, case is | |
| * if the same strip is used in different DDL recordings. Since the texture strip atlases aren't | |
| * dedupped across threads, if the same strip is used in two different DDL recordings it will | |
| * be duplicated in both of the DDL recorders' atlases. | |
| * Note, one additional feature of the DDL texture strip atlases is that, if DDL recording is ended | |
| * before one of the large textures is full, the large texture will be "shrunk" to fit its | |
| * contents. | |
| */ | |
| class GrDDLTextureStripAtlas final : public GrTextureStripAtlas { | |
| public: | |
| ~GrDDLTextureStripAtlas() final; | |
| // Overrides from GrTextureStripAtlas | |
| void lockRow(int row) final { /* The DDL version doesn't lock & unlock individual rows */} | |
| void unlockRow(int row) final { /* The DDL version doesn't lock & unlock individual rows */} | |
| // Caution: this method will only return the appropriate proxy after a successful 'addStrip' | |
| // call has been made. Additionally, the proxy return will be fully lazy (i.e., its final | |
| // height will be unknown). | |
| sk_sp<GrTextureProxy> asTextureProxyRef() const final { | |
| SkASSERT(fCurProxy); | |
| return fCurProxy; | |
| } | |
| private: | |
| friend class GrTextureStripAtlasManager; // for ctor | |
| // Overrides from GrTextureStripAtlas | |
| int addStrip(GrContext*, const SkBitmap&) final; | |
| void finish(GrProxyProvider*) final; | |
| /** | |
| * The state of a single row in our cache. For the DDL texture strip atlas we hold onto all | |
| * the individual strip bitmaps and, upon finish, combine them all into a single bitmap. | |
| */ | |
| struct AtlasRow : ::SkNoncopyable { | |
| AtlasRow() {} | |
| SkBitmap fBitmap; | |
| }; | |
| /** | |
| * Only the GrTextureStripAtlasManager is allowed to create GrDDLTextureStripAtlas | |
| */ | |
| GrDDLTextureStripAtlas(const Desc& desc); | |
| /** | |
| * Searches the key table for a key and returns the index if found; if not found, it returns | |
| * the bitwise not of the index at which we could insert the key to maintain a sorted list. | |
| **/ | |
| int searchByKey(uint32_t key); | |
| SkDEBUGCODE(void validate();) | |
| sk_sp<GrTextureProxy> fCurProxy; // the lazy proxy that will be split off in the finish call | |
| SkBitmap* fAtlasBitmap; // the bitmap backing 'fCurProxy' | |
| const uint16_t fMaxNumRows; | |
| uint16_t fCurRow; | |
| AtlasRow* fRows; // We just store the source bitmap for each row. | |
| // A list of pointers to AtlasRows that currently contain cached images, sorted by key | |
| SkTDArray<AtlasRow*> fKeyTable; | |
| typedef GrTextureStripAtlas INHERITED; | |
| }; | |
| #endif |