Make GrTextureStripAtlas DDL friendly
Change-Id: If8fdd7a1c027bc2b2791cfe1af13f99c2561d93d Reviewed-on: https://skia-review.googlesource.com/113268 Reviewed-by: Brian Salomon <bsalomon@google.com> Commit-Queue: Robert Phillips <robertphillips@google.com>
This commit is contained in:
parent
afdc6b1ba9
commit
41a3b87846
@ -42,6 +42,7 @@ class GrSwizzle;
|
|||||||
class GrTextBlobCache;
|
class GrTextBlobCache;
|
||||||
class GrTextContext;
|
class GrTextContext;
|
||||||
class GrTextureProxy;
|
class GrTextureProxy;
|
||||||
|
class GrTextureStripAtlasManager;
|
||||||
class GrVertexBuffer;
|
class GrVertexBuffer;
|
||||||
struct GrVkBackendContext;
|
struct GrVkBackendContext;
|
||||||
|
|
||||||
@ -98,24 +99,6 @@ public:
|
|||||||
*/
|
*/
|
||||||
void resetContext(uint32_t state = kAll_GrBackendState);
|
void resetContext(uint32_t state = kAll_GrBackendState);
|
||||||
|
|
||||||
/**
|
|
||||||
* Callback function to allow classes to cleanup on GrContext destruction.
|
|
||||||
* The 'info' field is filled in with the 'info' passed to addCleanUp.
|
|
||||||
*/
|
|
||||||
typedef void (*PFCleanUpFunc)(const GrContext* context, void* info);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Add a function to be called from within GrContext's destructor.
|
|
||||||
* This gives classes a chance to free resources held on a per context basis.
|
|
||||||
* The 'info' parameter will be stored and passed to the callback function.
|
|
||||||
*/
|
|
||||||
void addCleanUp(PFCleanUpFunc cleanUp, void* info) {
|
|
||||||
CleanUpData* entry = fCleanUpData.push();
|
|
||||||
|
|
||||||
entry->fFunc = cleanUp;
|
|
||||||
entry->fInfo = info;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Abandons all GPU resources and assumes the underlying backend 3D API context is no longer
|
* Abandons all GPU resources and assumes the underlying backend 3D API context is no longer
|
||||||
* usable. Call this if you have lost the associated GPU context, and thus internal texture,
|
* usable. Call this if you have lost the associated GPU context, and thus internal texture,
|
||||||
@ -293,6 +276,7 @@ private:
|
|||||||
GrResourceCache* fResourceCache;
|
GrResourceCache* fResourceCache;
|
||||||
GrResourceProvider* fResourceProvider;
|
GrResourceProvider* fResourceProvider;
|
||||||
GrProxyProvider* fProxyProvider;
|
GrProxyProvider* fProxyProvider;
|
||||||
|
std::unique_ptr<GrTextureStripAtlasManager> fTextureStripAtlasManager;
|
||||||
|
|
||||||
|
|
||||||
GrGlyphCache* fGlyphCache;
|
GrGlyphCache* fGlyphCache;
|
||||||
@ -311,13 +295,6 @@ private:
|
|||||||
|
|
||||||
std::unique_ptr<SkTaskGroup> fTaskGroup;
|
std::unique_ptr<SkTaskGroup> fTaskGroup;
|
||||||
|
|
||||||
struct CleanUpData {
|
|
||||||
PFCleanUpFunc fFunc;
|
|
||||||
void* fInfo;
|
|
||||||
};
|
|
||||||
|
|
||||||
SkTDArray<CleanUpData> fCleanUpData;
|
|
||||||
|
|
||||||
const uint32_t fUniqueID;
|
const uint32_t fUniqueID;
|
||||||
|
|
||||||
std::unique_ptr<GrDrawingManager> fDrawingManager;
|
std::unique_ptr<GrDrawingManager> fDrawingManager;
|
||||||
|
@ -444,16 +444,16 @@ std::unique_ptr<GrFragmentProcessor> ColorTableEffect::Make(GrContext* context,
|
|||||||
desc.fWidth = bitmap.width();
|
desc.fWidth = bitmap.width();
|
||||||
desc.fHeight = 128;
|
desc.fHeight = 128;
|
||||||
desc.fRowHeight = bitmap.height();
|
desc.fRowHeight = bitmap.height();
|
||||||
// TODO: this seems a bit heavy handed (passing a GrContext as part of the desc)
|
|
||||||
desc.fContext = context;
|
|
||||||
desc.fConfig = SkImageInfo2GrPixelConfig(bitmap.info(), *context->caps());
|
desc.fConfig = SkImageInfo2GrPixelConfig(bitmap.info(), *context->caps());
|
||||||
|
|
||||||
if (kUnknown_GrPixelConfig == desc.fConfig) {
|
if (kUnknown_GrPixelConfig == desc.fConfig) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
GrTextureStripAtlas* atlas = GrTextureStripAtlas::GetAtlas(desc);
|
auto atlasManager = context->contextPriv().textureStripAtlasManager();
|
||||||
int row = atlas->lockRow(bitmap);
|
|
||||||
|
GrTextureStripAtlas* atlas = atlasManager->getAtlas(desc);
|
||||||
|
int row = atlas->lockRow(context, bitmap);
|
||||||
sk_sp<GrTextureProxy> proxy;
|
sk_sp<GrTextureProxy> proxy;
|
||||||
if (-1 == row) {
|
if (-1 == row) {
|
||||||
atlas = nullptr;
|
atlas = nullptr;
|
||||||
|
@ -24,6 +24,7 @@
|
|||||||
#include "GrSurfaceProxyPriv.h"
|
#include "GrSurfaceProxyPriv.h"
|
||||||
#include "GrTexture.h"
|
#include "GrTexture.h"
|
||||||
#include "GrTextureContext.h"
|
#include "GrTextureContext.h"
|
||||||
|
#include "GrTextureStripAtlas.h"
|
||||||
#include "GrTracing.h"
|
#include "GrTracing.h"
|
||||||
#include "SkConvertPixels.h"
|
#include "SkConvertPixels.h"
|
||||||
#include "SkDeferredDisplayList.h"
|
#include "SkDeferredDisplayList.h"
|
||||||
@ -90,6 +91,8 @@ bool GrContext::initCommon(const GrContextOptions& options) {
|
|||||||
fResourceCache->setProxyProvider(fProxyProvider);
|
fResourceCache->setProxyProvider(fProxyProvider);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fTextureStripAtlasManager.reset(new GrTextureStripAtlasManager);
|
||||||
|
|
||||||
fDisableGpuYUVConversion = options.fDisableGpuYUVConversion;
|
fDisableGpuYUVConversion = options.fDisableGpuYUVConversion;
|
||||||
fSharpenMipmappedTextures = options.fSharpenMipmappedTextures;
|
fSharpenMipmappedTextures = options.fSharpenMipmappedTextures;
|
||||||
fDidTestPMConversions = false;
|
fDidTestPMConversions = false;
|
||||||
@ -146,10 +149,7 @@ GrContext::~GrContext() {
|
|||||||
fDrawingManager->cleanup();
|
fDrawingManager->cleanup();
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 0; i < fCleanUpData.count(); ++i) {
|
fTextureStripAtlasManager = nullptr;
|
||||||
(*fCleanUpData[i].fFunc)(this, fCleanUpData[i].fInfo);
|
|
||||||
}
|
|
||||||
|
|
||||||
delete fResourceProvider;
|
delete fResourceProvider;
|
||||||
delete fResourceCache;
|
delete fResourceCache;
|
||||||
delete fProxyProvider;
|
delete fProxyProvider;
|
||||||
@ -199,6 +199,7 @@ SkSurfaceCharacterization GrContextThreadSafeProxy::createCharacterization(
|
|||||||
void GrContext::abandonContext() {
|
void GrContext::abandonContext() {
|
||||||
ASSERT_SINGLE_OWNER
|
ASSERT_SINGLE_OWNER
|
||||||
|
|
||||||
|
fTextureStripAtlasManager->abandon();
|
||||||
fProxyProvider->abandon();
|
fProxyProvider->abandon();
|
||||||
fResourceProvider->abandon();
|
fResourceProvider->abandon();
|
||||||
|
|
||||||
@ -219,6 +220,7 @@ void GrContext::abandonContext() {
|
|||||||
void GrContext::releaseResourcesAndAbandonContext() {
|
void GrContext::releaseResourcesAndAbandonContext() {
|
||||||
ASSERT_SINGLE_OWNER
|
ASSERT_SINGLE_OWNER
|
||||||
|
|
||||||
|
fTextureStripAtlasManager->abandon();
|
||||||
fProxyProvider->abandon();
|
fProxyProvider->abandon();
|
||||||
fResourceProvider->abandon();
|
fResourceProvider->abandon();
|
||||||
|
|
||||||
|
@ -186,6 +186,10 @@ public:
|
|||||||
|
|
||||||
GrResourceCache* getResourceCache() { return fContext->fResourceCache; }
|
GrResourceCache* getResourceCache() { return fContext->fResourceCache; }
|
||||||
|
|
||||||
|
GrTextureStripAtlasManager* textureStripAtlasManager() {
|
||||||
|
return fContext->fTextureStripAtlasManager.get();
|
||||||
|
}
|
||||||
|
|
||||||
GrGpu* getGpu() { return fContext->fGpu.get(); }
|
GrGpu* getGpu() { return fContext->fGpu.get(); }
|
||||||
const GrGpu* getGpu() const { return fContext->fGpu.get(); }
|
const GrGpu* getGpu() const { return fContext->fGpu.get(); }
|
||||||
|
|
||||||
|
@ -26,10 +26,9 @@ class GrTextureStripAtlas {
|
|||||||
public:
|
public:
|
||||||
/**
|
/**
|
||||||
* Descriptor struct which we'll use as a hash table key
|
* Descriptor struct which we'll use as a hash table key
|
||||||
**/
|
*/
|
||||||
struct Desc {
|
struct Desc {
|
||||||
Desc() { sk_bzero(this, sizeof(*this)); }
|
Desc() { sk_bzero(this, sizeof(*this)); }
|
||||||
GrContext* fContext;
|
|
||||||
GrPixelConfig fConfig;
|
GrPixelConfig fConfig;
|
||||||
uint16_t fWidth, fHeight, fRowHeight;
|
uint16_t fWidth, fHeight, fRowHeight;
|
||||||
uint16_t fUnusedPadding;
|
uint16_t fUnusedPadding;
|
||||||
@ -38,11 +37,6 @@ public:
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
|
||||||
* Try to find an atlas with the required parameters, creates a new one if necessary
|
|
||||||
*/
|
|
||||||
static GrTextureStripAtlas* GetAtlas(const Desc& desc);
|
|
||||||
|
|
||||||
~GrTextureStripAtlas();
|
~GrTextureStripAtlas();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -51,7 +45,8 @@ public:
|
|||||||
* @return The row index we inserted into, or -1 if we failed to find an open row. The caller
|
* @return The row index we inserted into, or -1 if we failed to find an open row. The caller
|
||||||
* is responsible for calling unlockRow() with this row index when it's done with it.
|
* is responsible for calling unlockRow() with this row index when it's done with it.
|
||||||
*/
|
*/
|
||||||
int lockRow(const SkBitmap& data);
|
int lockRow(GrContext*, const SkBitmap&);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This is intended to be used when cloning a processor that already holds a lock. It is
|
* This is intended to be used when cloning a processor that already holds a lock. It is
|
||||||
* assumed that the row already has at least one lock.
|
* assumed that the row already has at least one lock.
|
||||||
@ -78,11 +73,12 @@ public:
|
|||||||
SkScalar getYOffset(int row) const { return SkIntToScalar(row) / fNumRows; }
|
SkScalar getYOffset(int row) const { return SkIntToScalar(row) / fNumRows; }
|
||||||
SkScalar getNormalizedTexelHeight() const { return fNormalizedYHeight; }
|
SkScalar getNormalizedTexelHeight() const { return fNormalizedYHeight; }
|
||||||
|
|
||||||
GrContext* getContext() const { return fDesc.fContext; }
|
|
||||||
|
|
||||||
sk_sp<GrTextureProxy> asTextureProxyRef() const;
|
sk_sp<GrTextureProxy> asTextureProxyRef() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
friend class GrTextureStripAtlasManager; // for ctor
|
||||||
|
|
||||||
|
static uint32_t CreateUniqueID();
|
||||||
|
|
||||||
// Key to indicate an atlas row without any meaningful data stored in it
|
// Key to indicate an atlas row without any meaningful data stored in it
|
||||||
const static uint32_t kEmptyAtlasRowKey = 0xffffffff;
|
const static uint32_t kEmptyAtlasRowKey = 0xffffffff;
|
||||||
@ -103,11 +99,11 @@ private:
|
|||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* We'll only allow construction via the static GrTextureStripAtlas::GetAtlas
|
* Only the GrTextureStripAtlasManager is allowed to create GrTextureStripAtlases
|
||||||
*/
|
*/
|
||||||
GrTextureStripAtlas(Desc desc);
|
GrTextureStripAtlas(const Desc& desc);
|
||||||
|
|
||||||
void lockTexture();
|
void lockTexture(GrContext*);
|
||||||
void unlockTexture();
|
void unlockTexture();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -116,7 +112,8 @@ private:
|
|||||||
void initLRU();
|
void initLRU();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Grabs the least recently used free row out of the LRU list, returns nullptr if no rows are free.
|
* Grabs the least recently used free row out of the LRU list, returns nullptr if no rows
|
||||||
|
* are free.
|
||||||
*/
|
*/
|
||||||
AtlasRow* getLRU();
|
AtlasRow* getLRU();
|
||||||
|
|
||||||
@ -140,37 +137,9 @@ private:
|
|||||||
void validate();
|
void validate();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/**
|
// A unique ID for this atlas, so we can be sure that if we
|
||||||
* Clean up callback registered with GrContext. Allows this class to
|
|
||||||
* free up any allocated AtlasEntry and GrTextureStripAtlas objects
|
|
||||||
*/
|
|
||||||
static void CleanUp(const GrContext* context, void* info);
|
|
||||||
|
|
||||||
// Hash table entry for atlases
|
|
||||||
class AtlasEntry : public ::SkNoncopyable {
|
|
||||||
public:
|
|
||||||
// for SkTDynamicHash
|
|
||||||
static const Desc& GetKey(const AtlasEntry& entry) { return entry.fDesc; }
|
|
||||||
static uint32_t Hash(const Desc& desc) { return SkOpts::hash(&desc, sizeof(Desc)); }
|
|
||||||
|
|
||||||
// AtlasEntry proper
|
|
||||||
AtlasEntry() : fAtlas(nullptr) {}
|
|
||||||
~AtlasEntry() { delete fAtlas; }
|
|
||||||
Desc fDesc;
|
|
||||||
GrTextureStripAtlas* fAtlas;
|
|
||||||
};
|
|
||||||
|
|
||||||
class Hash;
|
|
||||||
static Hash* gAtlasCache;
|
|
||||||
|
|
||||||
static Hash* GetCache();
|
|
||||||
|
|
||||||
// We increment gCacheCount for each atlas
|
|
||||||
static int32_t gCacheCount;
|
|
||||||
|
|
||||||
// A unique ID for this texture (formed with: gCacheCount++), so we can be sure that if we
|
|
||||||
// get a texture back from the texture cache, that it's the same one we last used.
|
// get a texture back from the texture cache, that it's the same one we last used.
|
||||||
const int32_t fCacheKey;
|
const uint32_t fCacheKey;
|
||||||
|
|
||||||
// Total locks on all rows (when this reaches zero, we can unlock our texture)
|
// Total locks on all rows (when this reaches zero, we can unlock our texture)
|
||||||
int32_t fLockedRows;
|
int32_t fLockedRows;
|
||||||
@ -195,4 +164,45 @@ private:
|
|||||||
SkTDArray<AtlasRow*> fKeyTable;
|
SkTDArray<AtlasRow*> fKeyTable;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class GrTextureStripAtlasManager {
|
||||||
|
public:
|
||||||
|
GrTextureStripAtlasManager() {}
|
||||||
|
~GrTextureStripAtlasManager();
|
||||||
|
|
||||||
|
void abandon();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Try to find an atlas with the required parameters, creates a new one if necessary
|
||||||
|
*/
|
||||||
|
GrTextureStripAtlas* getAtlas(const GrTextureStripAtlas::Desc&);
|
||||||
|
|
||||||
|
private:
|
||||||
|
void deleteAllAtlases();
|
||||||
|
|
||||||
|
// Hash table entry for atlases
|
||||||
|
class AtlasEntry : public ::SkNoncopyable {
|
||||||
|
public:
|
||||||
|
AtlasEntry(const GrTextureStripAtlas::Desc& desc, GrTextureStripAtlas* atlas)
|
||||||
|
: fDesc(desc)
|
||||||
|
, fAtlas(atlas) {
|
||||||
|
}
|
||||||
|
~AtlasEntry() { delete fAtlas; }
|
||||||
|
|
||||||
|
// for SkTDynamicHash
|
||||||
|
static const GrTextureStripAtlas::Desc& GetKey(const AtlasEntry& entry) {
|
||||||
|
return entry.fDesc;
|
||||||
|
}
|
||||||
|
static uint32_t Hash(const GrTextureStripAtlas::Desc& desc) {
|
||||||
|
return SkOpts::hash(&desc, sizeof(GrTextureStripAtlas::Desc));
|
||||||
|
}
|
||||||
|
|
||||||
|
const GrTextureStripAtlas::Desc fDesc;
|
||||||
|
GrTextureStripAtlas* fAtlas;
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef SkTDynamicHash<AtlasEntry, GrTextureStripAtlas::Desc> AtlasHash;
|
||||||
|
|
||||||
|
AtlasHash fAtlasCache;
|
||||||
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -20,59 +20,50 @@
|
|||||||
#define VALIDATE
|
#define VALIDATE
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
class GrTextureStripAtlas::Hash : public SkTDynamicHash<GrTextureStripAtlas::AtlasEntry,
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
GrTextureStripAtlas::Desc> {};
|
GrTextureStripAtlasManager::~GrTextureStripAtlasManager() {
|
||||||
|
this->deleteAllAtlases();
|
||||||
int32_t GrTextureStripAtlas::gCacheCount = 0;
|
|
||||||
|
|
||||||
// DDL TODO: The texture strip atlas can't have this global!
|
|
||||||
GrTextureStripAtlas::Hash* GrTextureStripAtlas::gAtlasCache = nullptr;
|
|
||||||
|
|
||||||
GrTextureStripAtlas::Hash* GrTextureStripAtlas::GetCache() {
|
|
||||||
|
|
||||||
if (nullptr == gAtlasCache) {
|
|
||||||
gAtlasCache = new Hash;
|
|
||||||
}
|
|
||||||
|
|
||||||
return gAtlasCache;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Remove the specified atlas from the cache
|
void GrTextureStripAtlasManager::deleteAllAtlases() {
|
||||||
void GrTextureStripAtlas::CleanUp(const GrContext*, void* info) {
|
AtlasHash::Iter iter(&fAtlasCache);
|
||||||
SkASSERT(info);
|
while (!iter.done()) {
|
||||||
|
AtlasEntry* tmp = &(*iter);
|
||||||
AtlasEntry* entry = static_cast<AtlasEntry*>(info);
|
++iter;
|
||||||
|
delete tmp;
|
||||||
// remove the cache entry
|
|
||||||
GetCache()->remove(entry->fDesc);
|
|
||||||
|
|
||||||
// remove the actual entry
|
|
||||||
delete entry;
|
|
||||||
|
|
||||||
if (0 == GetCache()->count()) {
|
|
||||||
delete gAtlasCache;
|
|
||||||
gAtlasCache = nullptr;
|
|
||||||
}
|
}
|
||||||
|
fAtlasCache.reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
GrTextureStripAtlas* GrTextureStripAtlas::GetAtlas(const GrTextureStripAtlas::Desc& desc) {
|
void GrTextureStripAtlasManager::abandon() {
|
||||||
AtlasEntry* entry = GetCache()->find(desc);
|
this->deleteAllAtlases();
|
||||||
if (nullptr == entry) {
|
}
|
||||||
entry = new AtlasEntry;
|
|
||||||
|
|
||||||
entry->fAtlas = new GrTextureStripAtlas(desc);
|
GrTextureStripAtlas* GrTextureStripAtlasManager::getAtlas(const GrTextureStripAtlas::Desc& desc) {
|
||||||
entry->fDesc = desc;
|
AtlasEntry* entry = fAtlasCache.find(desc);
|
||||||
|
if (!entry) {
|
||||||
|
// TODO: Does the AtlasEntry need a copy of the Desc if the GrTextureStripAtlas has one?
|
||||||
|
entry = new AtlasEntry(desc, new GrTextureStripAtlas(desc));
|
||||||
|
|
||||||
desc.fContext->addCleanUp(CleanUp, entry);
|
fAtlasCache.add(entry);
|
||||||
|
|
||||||
GetCache()->add(entry);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return entry->fAtlas;
|
return entry->fAtlas;
|
||||||
}
|
}
|
||||||
|
|
||||||
GrTextureStripAtlas::GrTextureStripAtlas(GrTextureStripAtlas::Desc desc)
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
: fCacheKey(sk_atomic_inc(&gCacheCount))
|
uint32_t GrTextureStripAtlas::CreateUniqueID() {
|
||||||
|
static int32_t gUniqueID = SK_InvalidUniqueID;
|
||||||
|
uint32_t id;
|
||||||
|
// Loop in case our global wraps around, as we never want to return a 0.
|
||||||
|
do {
|
||||||
|
id = static_cast<uint32_t>(sk_atomic_inc(&gUniqueID) + 1);
|
||||||
|
} while (id == SK_InvalidUniqueID);
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
GrTextureStripAtlas::GrTextureStripAtlas(const Desc& desc)
|
||||||
|
: fCacheKey(CreateUniqueID())
|
||||||
, fLockedRows(0)
|
, fLockedRows(0)
|
||||||
, fDesc(desc)
|
, fDesc(desc)
|
||||||
, fNumRows(desc.fHeight / desc.fRowHeight)
|
, fNumRows(desc.fHeight / desc.fRowHeight)
|
||||||
@ -94,10 +85,10 @@ void GrTextureStripAtlas::lockRow(int row) {
|
|||||||
++fLockedRows;
|
++fLockedRows;
|
||||||
}
|
}
|
||||||
|
|
||||||
int GrTextureStripAtlas::lockRow(const SkBitmap& bitmap) {
|
int GrTextureStripAtlas::lockRow(GrContext* context, const SkBitmap& bitmap) {
|
||||||
VALIDATE;
|
VALIDATE;
|
||||||
|
|
||||||
if (!this->getContext()->contextPriv().resourceProvider()) {
|
if (!context->contextPriv().resourceProvider()) {
|
||||||
// DDL TODO: For DDL we need to schedule inline & ASAP uploads. However these systems
|
// DDL TODO: For DDL we need to schedule inline & ASAP uploads. However these systems
|
||||||
// currently use the flushState which we can't use for the opList-based DDL phase.
|
// currently use the flushState which we can't use for the opList-based DDL phase.
|
||||||
// For the opList-based solution every texture strip will get its own texture proxy.
|
// For the opList-based solution every texture strip will get its own texture proxy.
|
||||||
@ -106,7 +97,7 @@ int GrTextureStripAtlas::lockRow(const SkBitmap& bitmap) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (0 == fLockedRows) {
|
if (0 == fLockedRows) {
|
||||||
this->lockTexture();
|
this->lockTexture(context);
|
||||||
if (!fTexContext) {
|
if (!fTexContext) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@ -139,7 +130,7 @@ int GrTextureStripAtlas::lockRow(const SkBitmap& bitmap) {
|
|||||||
|
|
||||||
if (nullptr == row) {
|
if (nullptr == row) {
|
||||||
// force a flush, which should unlock all the rows; then try again
|
// force a flush, which should unlock all the rows; then try again
|
||||||
fDesc.fContext->contextPriv().flush(nullptr); // tighten this up?
|
context->contextPriv().flush(nullptr); // tighten this up?
|
||||||
row = this->getLRU();
|
row = this->getLRU();
|
||||||
if (nullptr == row) {
|
if (nullptr == row) {
|
||||||
--fLockedRows;
|
--fLockedRows;
|
||||||
@ -209,7 +200,7 @@ GrTextureStripAtlas::AtlasRow* GrTextureStripAtlas::getLRU() {
|
|||||||
return row;
|
return row;
|
||||||
}
|
}
|
||||||
|
|
||||||
void GrTextureStripAtlas::lockTexture() {
|
void GrTextureStripAtlas::lockTexture(GrContext* context) {
|
||||||
|
|
||||||
static const GrUniqueKey::Domain kDomain = GrUniqueKey::GenerateDomain();
|
static const GrUniqueKey::Domain kDomain = GrUniqueKey::GenerateDomain();
|
||||||
GrUniqueKey key;
|
GrUniqueKey key;
|
||||||
@ -217,7 +208,7 @@ void GrTextureStripAtlas::lockTexture() {
|
|||||||
builder[0] = static_cast<uint32_t>(fCacheKey);
|
builder[0] = static_cast<uint32_t>(fCacheKey);
|
||||||
builder.finish();
|
builder.finish();
|
||||||
|
|
||||||
GrProxyProvider* proxyProvider = fDesc.fContext->contextPriv().proxyProvider();
|
GrProxyProvider* proxyProvider = context->contextPriv().proxyProvider();
|
||||||
|
|
||||||
sk_sp<GrTextureProxy> proxy = proxyProvider->findOrCreateProxyByUniqueKey(
|
sk_sp<GrTextureProxy> proxy = proxyProvider->findOrCreateProxyByUniqueKey(
|
||||||
key, kTopLeft_GrSurfaceOrigin);
|
key, kTopLeft_GrSurfaceOrigin);
|
||||||
@ -240,7 +231,7 @@ void GrTextureStripAtlas::lockTexture() {
|
|||||||
fKeyTable.rewind();
|
fKeyTable.rewind();
|
||||||
}
|
}
|
||||||
SkASSERT(proxy);
|
SkASSERT(proxy);
|
||||||
fTexContext = fDesc.fContext->contextPriv().makeWrappedSurfaceContext(std::move(proxy));
|
fTexContext = context->contextPriv().makeWrappedSurfaceContext(std::move(proxy));
|
||||||
}
|
}
|
||||||
|
|
||||||
void GrTextureStripAtlas::unlockTexture() {
|
void GrTextureStripAtlas::unlockTexture() {
|
||||||
|
@ -1291,21 +1291,21 @@ GrGradientEffect::GrGradientEffect(ClassID classID, const CreateArgs& args, bool
|
|||||||
shader.getGradientTableBitmap(&bitmap, bitmapType);
|
shader.getGradientTableBitmap(&bitmap, bitmapType);
|
||||||
SkASSERT(1 == bitmap.height() && SkIsPow2(bitmap.width()));
|
SkASSERT(1 == bitmap.height() && SkIsPow2(bitmap.width()));
|
||||||
|
|
||||||
|
auto atlasManager = args.fContext->contextPriv().textureStripAtlasManager();
|
||||||
|
|
||||||
GrTextureStripAtlas::Desc desc;
|
GrTextureStripAtlas::Desc desc;
|
||||||
desc.fWidth = bitmap.width();
|
desc.fWidth = bitmap.width();
|
||||||
desc.fHeight = 32;
|
desc.fHeight = 32;
|
||||||
desc.fRowHeight = bitmap.height(); // always 1 here
|
desc.fRowHeight = bitmap.height(); // always 1 here
|
||||||
desc.fContext = args.fContext;
|
|
||||||
desc.fConfig = SkImageInfo2GrPixelConfig(bitmap.info(), *args.fContext->caps());
|
desc.fConfig = SkImageInfo2GrPixelConfig(bitmap.info(), *args.fContext->caps());
|
||||||
fAtlas = GrTextureStripAtlas::GetAtlas(desc);
|
fAtlas = atlasManager->getAtlas(desc);
|
||||||
SkASSERT(fAtlas);
|
SkASSERT(fAtlas);
|
||||||
|
|
||||||
// We always filter the gradient table. Each table is one row of a texture, always
|
// We always filter the gradient table. Each table is one row of a texture, always
|
||||||
// y-clamp.
|
// y-clamp.
|
||||||
GrSamplerState samplerState(args.fWrapMode, GrSamplerState::Filter::kBilerp);
|
GrSamplerState samplerState(args.fWrapMode, GrSamplerState::Filter::kBilerp);
|
||||||
|
|
||||||
fRow = fAtlas->lockRow(bitmap);
|
fRow = fAtlas->lockRow(args.fContext, bitmap);
|
||||||
if (-1 != fRow) {
|
if (-1 != fRow) {
|
||||||
fYCoord = fAtlas->getYOffset(fRow)+SK_ScalarHalf*fAtlas->getNormalizedTexelHeight();
|
fYCoord = fAtlas->getYOffset(fRow)+SK_ScalarHalf*fAtlas->getNormalizedTexelHeight();
|
||||||
// This is 1/2 places where auto-normalization is disabled
|
// This is 1/2 places where auto-normalization is disabled
|
||||||
|
Loading…
Reference in New Issue
Block a user