Use device and key descriptors

Change-Id: I2ac13303376f3d1464dd1e259637374a9c5ef237
Reviewed-on: https://skia-review.googlesource.com/125823
Commit-Queue: Herb Derby <herb@google.com>
Reviewed-by: Khushal Sagar <khushalsagar@google.com>
This commit is contained in:
Herb Derby 2018-05-03 17:05:30 -04:00 committed by Skia Commit-Bot
parent 60c67490a1
commit e1f566f2fd
3 changed files with 82 additions and 38 deletions

View File

@ -349,26 +349,41 @@ void SkTextBlobCacheDiffCanvas::processGlyphRun(
SK_ABORT("Bad matrix.");
}
SkScalerContextRec rec;
SkScalerContextRec deviceSpecificRec;
SkScalerContextRec keyRec;
SkScalerContextEffects effects;
// TODO(crbug.com/831354): The typeface proxy on the client does not replicate the
// filtering done by the typeface on the server.
const bool enableTypefaceFiltering = false;
SkScalerContext::MakeRecAndEffects(runPaint, &fSurfaceProps, &runMatrix,
SkScalerContextFlags::kFakeGammaAndBoostContrast, &rec,
&effects, enableTypefaceFiltering);
SkScalerContextFlags::kFakeGammaAndBoostContrast,
&deviceSpecificRec,
&effects, true);
TRACE_EVENT1("skia", "RecForDesc", "rec", TRACE_STR_COPY(rec.dump().c_str()));
auto desc = SkScalerContext::DescriptorGivenRecAndEffects(rec, effects);
auto* glyphCacheState = static_cast<SkStrikeServer*>(fStrikeServer)
->getOrCreateCache(runPaint.getTypeface(), std::move(desc));
SkScalerContext::MakeRecAndEffects(runPaint, &fSurfaceProps, &runMatrix,
SkScalerContextFlags::kFakeGammaAndBoostContrast,
&keyRec,
&effects, false);
TRACE_EVENT1("skia", "RecForDesc", "rec", TRACE_STR_COPY(keyRec.dump().c_str()));
// TODO: possible perf improvement - move descriptor calculation into getOrCreateCache.
auto deviceDescriptor =
SkScalerContext::DescriptorGivenRecAndEffects(deviceSpecificRec, effects);
auto keyDescriptor =
SkScalerContext::DescriptorGivenRecAndEffects(keyRec, effects);
auto* glyphCacheState =
static_cast<SkStrikeServer*>(fStrikeServer)
->getOrCreateCache(
runPaint.getTypeface(),
std::move(deviceDescriptor),
std::move(keyDescriptor));
SkASSERT(glyphCacheState);
bool isSubpixel = SkToBool(rec.fFlags & SkScalerContext::kSubpixelPositioning_Flag);
bool isSubpixel =
SkToBool(deviceSpecificRec.fFlags & SkScalerContext::kSubpixelPositioning_Flag);
SkAxisAlignment axisAlignment = SkAxisAlignment::kNone_SkAxisAlignment;
if (it.positioning() == SkTextBlob::kHorizontal_Positioning) {
axisAlignment = rec.computeAxisAlignmentForHText();
axisAlignment = deviceSpecificRec.computeAxisAlignmentForHText();
}
auto pos = it.pos();
const uint16_t* glyphs = it.glyphs();
@ -450,19 +465,23 @@ void SkStrikeServer::writeStrikeData(std::vector<uint8_t>* memory) {
}
SkStrikeServer::SkGlyphCacheState* SkStrikeServer::getOrCreateCache(
SkTypeface* tf, std::unique_ptr<SkDescriptor> desc) {
SkASSERT(desc);
SkTypeface* tf,
std::unique_ptr<SkDescriptor> deviceDesc,
std::unique_ptr<SkDescriptor> keyDesc) {
SkASSERT(deviceDesc);
SkASSERT(keyDesc);
// Already locked.
if (fLockedDescs.find(desc.get()) != fLockedDescs.end()) {
auto it = fRemoteGlyphStateMap.find(desc.get());
if (fLockedDescs.find(keyDesc.get()) != fLockedDescs.end()) {
auto it = fRemoteGlyphStateMap.find(keyDesc.get());
SkASSERT(it != fRemoteGlyphStateMap.end());
return it->second.get();
}
// Try to lock.
auto it = fRemoteGlyphStateMap.find(desc.get());
auto it = fRemoteGlyphStateMap.find(keyDesc.get());
if (it != fRemoteGlyphStateMap.end()) {
SkASSERT(it->second->getDeviceDescriptor() == *deviceDesc);
bool locked = fDiscardableHandleManager->lockHandle(it->second->discardable_handle_id());
if (locked) {
fLockedDescs.insert(it->first);
@ -474,27 +493,35 @@ SkStrikeServer::SkGlyphCacheState* SkStrikeServer::getOrCreateCache(
fRemoteGlyphStateMap.erase(it);
}
const SkFontID typeface_id = tf->uniqueID();
if (!fCachedTypefaces.contains(typeface_id)) {
fCachedTypefaces.add(typeface_id);
fTypefacesToSend.emplace_back(typeface_id, tf->countGlyphs(), tf->fontStyle(),
const SkFontID typefaceId = tf->uniqueID();
if (!fCachedTypefaces.contains(typefaceId)) {
fCachedTypefaces.add(typefaceId);
fTypefacesToSend.emplace_back(typefaceId, tf->countGlyphs(), tf->fontStyle(),
tf->isFixedPitch());
}
auto* desc_ptr = desc.get();
auto new_handle = fDiscardableHandleManager->createHandle();
auto cache_state = skstd::make_unique<SkGlyphCacheState>(std::move(desc), new_handle);
auto* cache_state_ptr = cache_state.get();
auto* keyDescPtr = keyDesc.get();
auto newHandle = fDiscardableHandleManager->createHandle();
auto cacheState = skstd::make_unique<SkGlyphCacheState>(
std::move(deviceDesc),
std::move(keyDesc),
newHandle);
auto* cacheStatePtr = cacheState.get();
fLockedDescs.insert(desc_ptr);
fRemoteGlyphStateMap[desc_ptr] = std::move(cache_state);
return cache_state_ptr;
fLockedDescs.insert(keyDescPtr);
fRemoteGlyphStateMap[keyDescPtr] = std::move(cacheState);
return cacheStatePtr;
}
SkStrikeServer::SkGlyphCacheState::SkGlyphCacheState(std::unique_ptr<SkDescriptor> desc,
uint32_t discardable_handle_id)
: fDesc(std::move(desc)), fDiscardableHandleId(discardable_handle_id) {
SkASSERT(fDesc);
SkStrikeServer::SkGlyphCacheState::SkGlyphCacheState(
std::unique_ptr<SkDescriptor> deviceDescriptor,
std::unique_ptr<SkDescriptor> keyDescriptor,
uint32_t discardable_handle_id)
: fDeviceDescriptor(std::move(deviceDescriptor))
, fKeyDescriptor(std::move(keyDescriptor))
, fDiscardableHandleId(discardable_handle_id) {
SkASSERT(fDeviceDescriptor);
SkASSERT(fKeyDescriptor);
}
SkStrikeServer::SkGlyphCacheState::~SkGlyphCacheState() = default;
@ -509,14 +536,14 @@ void SkStrikeServer::SkGlyphCacheState::addGlyph(SkTypeface* typeface,
// this glyph.
fCachedGlyphs.add(glyph);
fPendingGlyphs.push_back(glyph);
if (!fContext) fContext = typeface->createScalerContext(effects, fDesc.get(), false);
if (!fContext) fContext = typeface->createScalerContext(effects, fDeviceDescriptor.get(), false);
}
void SkStrikeServer::SkGlyphCacheState::writePendingGlyphs(Serializer* serializer) {
// Write the desc.
serializer->emplace<StrikeSpec>(fContext->getTypeface()->uniqueID(), fPendingGlyphs.size(),
fDiscardableHandleId);
serializer->writeDescriptor(*fDesc.get());
serializer->writeDescriptor(*fKeyDescriptor.get());
// Write FontMetrics.
SkPaint::FontMetrics fontMetrics;
@ -656,7 +683,6 @@ bool SkStrikeClient::readStrikeData(const volatile void* memory, size_t memorySi
sk_sp<SkTypeface> SkStrikeClient::deserializeTypeface(const void* buf, size_t len) {
WireTypeface wire;
if (len != sizeof(wire)) return nullptr;
memcpy(&wire, buf, sizeof(wire));
return addTypeface(wire);
}

View File

@ -117,7 +117,8 @@ public:
// Methods used internally in skia ------------------------------------------
class SkGlyphCacheState {
public:
SkGlyphCacheState(std::unique_ptr<SkDescriptor> desc,
SkGlyphCacheState(std::unique_ptr<SkDescriptor> deviceDescriptor,
std::unique_ptr<SkDescriptor> keyDescriptor,
SkDiscardableHandleId discardableHandleId);
~SkGlyphCacheState();
@ -125,6 +126,13 @@ public:
void writePendingGlyphs(Serializer* serializer);
bool has_pending_glyphs() const { return !fPendingGlyphs.empty(); }
SkDiscardableHandleId discardable_handle_id() const { return fDiscardableHandleId; }
const SkDescriptor& getDeviceDescriptor() {
return *fDeviceDescriptor;
}
const SkDescriptor& getKeyDescriptor() {
return *fKeyDescriptor;
}
private:
// The set of glyphs cached on the remote client.
@ -134,11 +142,19 @@ public:
// remote client.
std::vector<SkPackedGlyphID> fPendingGlyphs;
std::unique_ptr<SkDescriptor> fDesc;
// The device descriptor is used to create the scaler context. The glyphs to have the
// correct device rendering. The key descriptor is used for communication. The GPU side will
// create descriptors with out the device filtering, thus matching the key descriptor.
std::unique_ptr<SkDescriptor> fDeviceDescriptor;
std::unique_ptr<SkDescriptor> fKeyDescriptor;
const SkDiscardableHandleId fDiscardableHandleId = -1;
// The context built using fDeviceDescriptor
std::unique_ptr<SkScalerContext> fContext;
};
SkGlyphCacheState* getOrCreateCache(SkTypeface*, std::unique_ptr<SkDescriptor>);
SkGlyphCacheState* getOrCreateCache(
SkTypeface*, std::unique_ptr<SkDescriptor>, std::unique_ptr<SkDescriptor>);
private:
SkDescriptorMap<std::unique_ptr<SkGlyphCacheState>> fRemoteGlyphStateMap;

View File

@ -826,6 +826,8 @@ void SkScalerContext::MakeRecAndEffects(const SkPaint& paint,
bool enableTypefaceFiltering) {
SkASSERT(deviceMatrix == nullptr || !deviceMatrix->hasPerspective());
sk_bzero(rec, sizeof(SkScalerContextRec));
SkTypeface* typeface = SkPaintPriv::GetTypefaceOrDefault(paint);
rec->fFontID = typeface->uniqueID();