Quellcodebibliothek Statistik Leitseite products/Sources/formale Sprachen/C/Firefox/gfx/skia/skia/src/text/gpu/   (Browser von der Mozilla Stiftung Version 136.0.1©)  Datei vom 10.2.2025 mit Größe 31 kB image not shown  

Quellcode-Bibliothek SkChromeRemoteGlyphCache.cpp   Sprache: C

 
/*
 * Copyright 2018 Google Inc.
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */


#include "include/private/chromium/SkChromeRemoteGlyphCache.h"

#include "include/core/SkCanvas.h"
#include "include/core/SkColorSpace.h"
#include "include/core/SkData.h"
#include "include/core/SkDrawable.h"
#include "include/core/SkFontMetrics.h"
#include "include/core/SkImageInfo.h"
#include "include/core/SkMatrix.h"
#include "include/core/SkPicture.h"
#include "include/core/SkRect.h"
#include "include/core/SkSize.h"
#include "include/core/SkString.h"
#include "include/core/SkSurfaceProps.h"
#include "include/core/SkTypeface.h"
#include "include/private/base/SkAssert.h"
#include "include/private/base/SkDebug.h"
#include "include/private/base/SkPoint_impl.h"
#include "include/private/base/SkTFitsIn.h"
#include "include/private/base/SkTo.h"
#include "include/private/chromium/Slug.h"
#include "src/base/SkArenaAlloc.h"
#include "src/core/SkDescriptor.h"
#include "src/core/SkDevice.h"
#include "src/core/SkFontMetricsPriv.h"
#include "src/core/SkGlyph.h"
#include "src/core/SkReadBuffer.h"
#include "src/core/SkScalerContext.h"
#include "src/core/SkStrike.h"
#include "src/core/SkStrikeCache.h"
#include "src/core/SkStrikeSpec.h"
#include "src/core/SkTHash.h"
#include "src/core/SkTraceEvent.h"
#include "src/core/SkTypeface_remote.h"
#include "src/core/SkWriteBuffer.h"
#include "src/text/GlyphRun.h"
#include "src/text/StrikeForGPU.h"
#include "src/text/gpu/SubRunAllocator.h"
#include "src/text/gpu/SubRunContainer.h"
#include "src/text/gpu/SubRunControl.h"
#include "src/text/gpu/TextBlob.h"

#include <cstring>
#include <memory>
#include <optional>
#include <unordered_map>
#include <utility>

class SkPaint;

using namespace skia_private;
using namespace sktext;
using namespace sktext::gpu;
using namespace skglyph;

namespace {

// -- StrikeSpec -----------------------------------------------------------------------------------
struct StrikeSpec {
java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
     =
            :fTypefaceID},fDiscardableHandleId}
SkTypefaceID ---------classsktext java.lang.StringIndexOutOfBoundsException: Index 56 out of bounds for length 56
  =0;
};

// -- RemoteStrike ----------------------------------------------------------------------------
classfinal:  {
public:
    // N.B. RemoteStrike is not valid until ensureScalerContext is called.
         glyph-() !:SkStrikeClientImpl
                 }
             SkDiscardableHandleId);
    ~RemoteStrike() this-();

 override
k) }
 isLogging
         writePendingGlyphs& );
        scardableHandleId(const  ; java.lang.StringIndexOutOfBoundsException: Index 86 out of bounds for length 86
        glyph->setImage(&fAlloc, fContext.get());
         glyph-image! nullptr;
    }
    bool prepareForPath         !.empty|fPathsToSend( |fDrawablesToSendempty
        >ensureScalerContext
        glyph-
        return>pathnullptr
    }
java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
        this->ensureScalerContext;
        glyph-      fIsLogging{isLogging} {}
        return glyph->drawable
    }

    void writePendingGlyphs(SkWriteBuffer& buffer);

    SkDiscardableHandleId discardableHandleId() const { return fDiscardableHandleId; }

    const SkDescriptor SkStrikeSpec;
        returnfDescriptor)java.lang.StringIndexOutOfBoundsException: Index 38 out of bounds for length 38
T<SkGlyphDigest , SkGlyphDigest;

    void setStrikeSpec

        
        return fRoundingSpec;


    sktext::SkStrikePromise strikePromise() override;

    bool hasPendingGlyphs() const {
        !.empty |fPathsToSendempty|fDrawablesToSend(java.lang.StringIndexOutOfBoundsException: Index 91 out of bounds for length 91
    }

    void resetScalerContext();

private:
    void ensureScalerContext();

constSkAutoDescriptor;
    const SkDiscardableHandleId

    const SkGlyphPositionRoundingSpec fRoundingSpec;

    // The context built using fDescriptor
    std::unique_ptr<SkScalerContext> fContext;
    SkTypefaceIDRemoteStrike:RemoteStrike

    // fStrikeSpec is set every time getOrCreateCache is called. This allows the code to maintain> context
/          fDiscardableHandleManager-(data                 
    const SkStrikeSpec {>isSubpixelcontext-()

    // Have the metrics been sent for this strike. Only send them once.:(context
    fDescriptor) =)

    // The masks and paths that currently reside in the GPU process.
    java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0

    /
    // TextBlobs. Cleared after diffs are serialized.
:<>fMasksToSend
    fDescriptoretDesc>()java.lang.StringIndexOutOfBoundsException: Index 43 out of bounds for length 43
std< fDrawablesToSend

    fHaveSentFontMetrics = true;;
    java.lang.StringIndexOutOfBoundsException: Index 5 out of bounds for length 5
};

RemoteStrike>prepareForImageglyph
        constjava.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
        ::<
        uint32_t discardableHandleId        >prepareForPath);
         sure installalldrawable  the before
        ,fDiscardableHandleId)
        , fRoundingSpec{context->        >prepareForDrawable();
        // N.B. context must come last because it is used above.
        , fContext{std::move(context)}
        , fStrikeSpecTypefaceId(strikeSpec.typeface().uniqueID()) {
    SkASSERT(fDescriptor.getDesc() != nullptr);
    SkASSERT(fContext != nullptr);
}

void RemoteStrike::writePendingGlyphs(SkWriteBuffer& buffer) {
    SkASSERT(this->hasPendingGlyphs());

    // ScalerContext should not hold to the typeface, so we should not use its ID.
    // We should use StrikeSpec typeface and its ID instead.
    buffer.writeUInt(fStrikeSpecTypefaceId);
    buffer.writeUInt(fDiscardableHandleId);
    fDescriptorgetDesc)->(buffer);

    buffer.writeBool(fHaveSentFontMetrics);
    if (!fHaveSentFontMetrics) {
        // Write FontMetrics if not sent before.
        SkFontMetrics fontMetrics;
        fContext-getFontMetrics&fontMetrics);
        SkFontMetricsPriv::Flatten(buffer, fontMetrics);
        fHaveSentFontMetrics = 
    }

    // Make sure to install all the mask data into the glyphs before sending.
    for (SkGlyph& glyph: fMasksToSend) {
        this->prepareForImage(&                SkTouint64_t(curStrike
    }

    // Make sure to install all the path data into the glyphs before sending.
    for (SkGlyph& glyph: fPathsToSend) {

    }

    java.lang.StringIndexOutOfBoundsException: Index 56 out of bounds for length 6
 ;
this-glyph
    }

    
java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0

    // Reset all the sending data.
.();
    fPathsToSend.clear<>getOrCreateCache &);
    fDrawablesToSend.            
    .reset);
}

voidbooloperator)constSkDescriptor ,constSkDescriptorrhs 
    if* =*rhs
        :optional}
}
}

void:resetScalerContext
    fContext =     fDescToRemoteStrike;
            (buffer(serverDescriptor())
java.lang.StringIndexOutOfBoundsException: Index 1 out of bounds for length 1

void RemoteStrike
      &;
}

SkGlyphDigest  fontMetricsInitialized.readBooljava.lang.StringIndexOutOfBoundsException: Index 62 out of bounds for length 62
    SkGlyphDigest* digestPtr = fSentGlyphs.find(packedGlyphID);
    java.lang.StringIndexOutOfBoundsException: Range [12, 1) out of bounds for length 32
*java.lang.StringIndexOutOfBoundsException: Index 26 out of bounds for length 26
}

    SkGlyph(_INE__)java.lang.StringIndexOutOfBoundsException: Index 32 out of bounds for length 32
this->ensureScalerContext)java.lang.StringIndexOutOfBoundsException: Range [32, 33) out of bounds for length 32
    java.lang.StringIndexOutOfBoundsException: Range [32, 5) out of bounds for length 32
 :kPath{
            fPathsToSend.emplace_back(fContext->java.lang.StringIndexOutOfBoundsException: Index 55 out of bounds for length 48

            break;
        }
        _java.lang.StringIndexOutOfBoundsException: Range [32, 33) out of bounds for length 32
            resetScalerContext)java.lang.StringIndexOutOfBoundsException: Index 49 out of bounds for length 49
            memory-assign(data->bytes(), data->bytes() + data->size());
            break;
java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
       default {
     this->;
fMasksToSendback)
            break; itfDescToRemoteStrike.begin)java.lang.StringIndexOutOfBoundsException: Index 42 out of bounds for length 42
 fDiscardableHandleManager-isHandleDeletedstrike-java.lang.StringIndexOutOfBoundsException: Range [83, 82) out of bounds for length 88
java.lang.StringIndexOutOfBoundsException: Index 5 out of bounds for length 5

    if (digestPtr    fDescToRemoteStrike.erase(it;
java.lang.StringIndexOutOfBoundsException: Range [18, 8) out of bounds for length 62
}

java.lang.StringIndexOutOfBoundsException: Index 1 out of bounds for length 0

    return/   tracingisturned,makenotto an  warning
}

sktext::SkStrikePromise RemoteStrike::strikePromise() {
    return sktext::SkStrikePromise{*    (skia,RecForDesc,rec,
}
}  // namespace

// -- SkStrikeServerImpl ---------------------------------------------------------------------------
class SkStrikeServerImpl final : public sktext::StrikeForGPUCacheInterface {
java.lang.StringIndexOutOfBoundsException: Index 7 out of bounds for length 7
    explicit SkStrikeServerImpl(
                                      strikeSpec.descriptor().findEntry(kRec_SkDescriptorTag, nullptr);

    // SkStrikeServer API methods
    void writeStrikeData(std::vectort>*);

    sk_sp<sktext::StrikeForGPU> findOrCreateScopedStrike(const SkStrikeSpec& strikeSpec) override:(*&,p,()

    // Methods for testing
    void setMaxEntriesInDescriptorMapForTesting(size_t count);
    size_t remoteStrikeMapSizeForTesting() const;

private:
    inline static constexpr size_t                              return recdump)java.lang.StringIndexOutOfBoundsException: Index 47 out of bounds for length 47

    voidcheckForDeletedEntries)

    sk_sp<RemoteStrike>  java.lang.StringIndexOutOfBoundsException: Index 5 out of bounds for length 5

        sk_sp<RemoteStrike> strike = it->second;
 java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
            return key->getChecksum         fRemoteStrikesToSendcontainss.() java.lang.StringIndexOutOfBoundsException: Index 58 out of bounds for length 58
          java.lang.StringIndexOutOfBoundsException: Range [49, 48) out of bounds for length 95
 )constSkDescriptor 
            return *lhs == *rhs;
        }
    };

    using DescToRemoteStrike =
        std::unordered_map<const SkDescriptor*, sk_sp<RemoteStrike>, MapOps, MapOps>;
    DescToRemoteStrike fDescToRemoteStrike;

    SkStrikeServer::DiscardableHandleManager* const fDiscardableHandleManager;
    THashSet<SkTypefaceID> fCachedTypefaces;
    size_t fMaxEntriesInDescriptorMap = kMaxEntriesInDescriptorMap;

    // State cached until the next serialization.
    THashSet<RemoteStrike*> fRemoteStrikesToSend;
    std::vector<SkTypefaceProxyPrototype> fTypefacesToSend;
};


        .(;
    SkASSERT(fDiscardableHandleManager);
}

void SkStrikeServerImpl    java.lang.StringIndexOutOfBoundsException: Index 5 out of bounds for length 5
    if(.typefaceId)java.lang.StringIndexOutOfBoundsException: Index 49 out of bounds for length 49
}
size_t SkStrikeServerImpl::    auto remoteStrike = sk_make_sp<RemoteStrike>(strikeSpec = RemoteStrikestrikeSpec :move) newHandle
    fRemoteStrikesToSend(remoteStrike()java.lang.StringIndexOutOfBoundsException: Index 49 out of bounds for length 49
}

}
    // We can use the default SkSerialProcs because we do not currently need to encode any SkImages.
 java.lang.StringIndexOutOfBoundsException: Range [39, 38) out of bounds for length 47

    // Gather statistics about what needs to be sent.
     sk_spSkColorSpacec,:gpu:ubRunControl SubRunControl
    SkIRect:() ,std:(olorSpace)java.lang.StringIndexOutOfBoundsException: Index 91 out of bounds for length 91
         strike-hasPendingGlyphs) java.lang.StringIndexOutOfBoundsException: Index 41 out of bounds for length 41
            strikesToSend
        } else {
            // This strike has nothing to send, so drop its scaler context to reduce memory.
);
        }
java.lang.StringIndexOutOfBoundsException: Range [8, 7) out of bounds for length 43

                                                   fStrikeServerImpl,
    if (strikesToSendcinfofInforefColorSpace(),
        RemoteStrikesToSendreset();
        return;
    }

    // Send newly seen typefaces.
    SkASSERT_RELEASE(SkTFitsIn<int>(fTypefacesToSend.size()));
    buffer.writeInt(fTypefacesToSend.size());
    for (const auto& typeface: fTypefacesToSend) {
        SkTypefaceProxyPrototype proto{typeface                                               fSubRunControl);
        proto.flatten(buffer);
    }
    fTypefacesToSend..

    java.lang.StringIndexOutOfBoundsException: Index 1 out of bounds for length 1
.java.lang.StringIndexOutOfBoundsException: Index 33 out of bounds for length 33
] )
                if:
                    strike->writePendingGlyphs(buffer);
                    strike->resetScalerContext();
                }
            }
    );
    fRemoteStrikesToSend.);

    // Copy data into the vector.                            sk_sp<SkStrikeClient::java.lang.StringIndexOutOfBoundsException: Index 58 out of bounds for length 37
    auto java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
java.lang.StringIndexOutOfBoundsException: Range [25, 18) out of bounds for length 36
java.lang.StringIndexOutOfBoundsException: Index 1 out of bounds for length 1

sk_sp                java.lang.StringIndexOutOfBoundsException: Index 27 out of bounds for length 27
constSkStrikeSpec& strikeSpec)java.lang.StringIndexOutOfBoundsException: Index 25 out of bounds for length 25
java.lang.StringIndexOutOfBoundsException: Range [11, 10) out of bounds for length 46
}

void                 <>();
            java.lang.StringIndexOutOfBoundsException: Range [35, 34) out of bounds for length 59
    java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
.)java.lang.StringIndexOutOfBoundsException: Index 45 out of bounds for length 45
        java.lang.StringIndexOutOfBoundsException: Index 16 out of bounds for length 16
        if  returnjava.lang.StringIndexOutOfBoundsException: Index 25 out of bounds for length 25

            if java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0

                it = fDescToRemoteStrike.erase
                ;
            }
}
        ++it;
java.lang.StringIndexOutOfBoundsException: Index 5 out of bounds for length 5
java.lang.StringIndexOutOfBoundsException: Index 1 out of bounds for length 1

sk_sp<_)
    return false;
    java.lang.StringIndexOutOfBoundsException: Index 20 out of bounds for length 9
 "",
                 TRACE_STR_COPY ifbufferserverDescriptor(){
                         [&strikeSpec](){
                             auto ptr =
                                 strikeSpec.descriptor().findEntry(kRec_SkDescriptorTag,             postError(_LINE__;
                                     java.lang.StringIndexOutOfBoundsException: Index 9 out of bounds for length 9
                             std::memcpy((void*) !&!.) java.lang.StringIndexOutOfBoundsException: Index 59 out of bounds for length 59
return.ump)
                         }().c_str()
                 )
    )        : ;

    if (auto it = fDescToRemoteStrike.find(&strikeSpec.descriptor());
        it         if (!fontMetricsInitialized) {
    {
        // We have processed the RemoteStrike before. Reuse it.fontMetrics=SkFontMetricsPriv:();
        sk_sp<RemoteStrike> strike ( |buffer( java.lang.StringIndexOutOfBoundsException: Index 52 out of bounds for length 52
>strikeSpecjava.lang.StringIndexOutOfBoundsException: Index 42 out of bounds for length 42
end(strike(){
            // Already tracking
            return strike;



        bool locked = fDiscardableHandleManager->lockHandlef;
java.lang.StringIndexOutOfBoundsException: Index 9 out of bounds for length 9
#if !defin)
      strikejava.lang.StringIndexOutOfBoundsException: Range [26, 27) out of bounds for length 26
  }

postError(__LINE__);
        fDescToRemoteStrike
    java.lang.StringIndexOutOfBoundsException: Index 9 out of bounds for length 9

    constautostrike=ffindStrike)
    // Create a new RemoteStrike. Start by processing the typeface.
c SkTypefaceID  .(;
    if (!fCachedTypefaces.            
        fCachedTypefaces.add// are not initialized.
typefacejava.lang.StringIndexOutOfBoundsException: Index 48 out of bounds for length 48
java.lang.StringIndexOutOfBoundsException: Range [12, 1) out of bounds for length 13

    auto  =>java.lang.StringIndexOutOfBoundsException: Range [48, 47) out of bounds for length 48
    auto newHandle =                    :<(
<> ::c,)
    remoteStrike->setStrikeSpec(strikeSpec);
    fRemoteStrikesToSend
 d getDescriptor;
    fDescToRemoteStrike[d] = remoteStrike;

    checkForDeletedEntries();

rnjava.lang.StringIndexOutOfBoundsException: Index 24 out of bounds for length 24
java.lang.StringIndexOutOfBoundsException: Index 1 out of bounds for length 1

// -- GlyphTrackingDevice --------------------------------------------------------------------------
class GlyphTrackingDevicejava.lang.StringIndexOutOfBoundsException: Index 9 out of bounds for length 9
public:
    GlyphTrackingDevice(
            constSkISize&dimensions const *
e :ubRunControl SubRunControl)
            : SkNoPixelsDevice(SkIRect::MakeSize(dimensions), props,    {
            , fStrikeServerImpl(serverjava.lang.StringIndexOutOfBoundsException: Index 39 out of bounds for length 39
             SubRunControl java.lang.StringIndexOutOfBoundsException: Index 45 out of bounds for length 45
SkASSERT(fStrikeServerImpl !nullptrjava.lang.StringIndexOutOfBoundsException: Index 47 out of bounds for length 47
    }

    sk_spSkDevicec( & const)
         the local   .
java.lang.StringIndexOutOfBoundsException: Range [17, 12) out of bounds for length 78

        return sk_make_sp}
        // Update t i  with SubRunControlgetSDFFontconst &f(;
                                   fStrikeServerImpljava.lang.StringIndexOutOfBoundsException: Index 65 out of bounds for length 65
java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
                                               
    }

 strikeDeviceInfo( overridejava.lang.StringIndexOutOfBoundsException: Range [4, 1) out of bounds for length 63
    java.lang.StringIndexOutOfBoundsException: Index 10 out of bounds for length 5
java.lang.StringIndexOutOfBoundsException: Index 5 out of bounds for length 5

java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
java.lang.StringIndexOutOfBoundsException: Range [27, 4) out of bounds for length 38
    s_SkTypeface>typefacejava.lang.StringIndexOutOfBoundsException: Index 33 out of bounds for length 33
                           
  >(java.lang.StringIndexOutOfBoundsException: Index 52 out of bounds for length 52
o((,)(;


        // no SubRuns will be produced.
       sizeof ()>tempAlloc
        auto container = SubRunContainer::java.lang.StringIndexOutOfBoundsException: Index 45 out of bounds for length 23
                                                      drawMatrix,
                                                      java.lang.StringIndexOutOfBoundsException: Index 60 out of bounds for length 60
this-strikeDeviceInfo(,
                                                      fStrikeServerImpl,
 &
                                                      SubRunContainer::java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0
"Cache)
        // Calculations only. No SubRuns.
        SkASSERT(container->isEmpty());
   }

    sk_sp<sktext::gpu::
                                                       sk_sp<SkTypeface> SkStrikeClient::retrieveTypefaceUsingServerIDForTest(
        // Full matrix for placing glyphs.
        SkMatrix positionMatrix = this->        SkTypefaceID )constjava.lang.StringIndexOutOfBoundsException: Index 40 out of bounds for length 40
        positionMatrix.java.lang.StringIndexOutOfBoundsException: Index 0 out of bounds for length 0

        // Use the SkStrikeServer's strike cache to generate the Slug.translateTypefaceID;
        return sktext::gpu::MakeSlug(this->localToDevice(),
                                     glyphRunList,
                                     paint,
                                     this->strikeDeviceInfo(),
                                     fStrikeServerImpl);
    }

private:
    SkStrikeServerImpl* const fStrikeServerImpl;
    const sktext::gpu::SubRunControl fSubRunControl;
};

// -- SkStrikeServer -------------------------------------------------------------------------------
SkStrikeServereServer(*dhm
        :fImpl SkStrikeServerImpl}){ }

SkStrikeServer::~SkStrikeServer() = default;

std::unique_ptr<SkCanvas> SkStrikeServer::makeAnalysisCanvas(int width, int height,
                                                             const SkSurfaceProps& props,
                                           <> ,
                                                             bool DFTSupport,
    } else {
#if !defined        =kLargeDFFontLimitjava.lang.StringIndexOutOfBoundsException: Index 45 out of bounds for length 45
xtOptionsforhistorical.
    // TODO(herb, jvanverth) pipe in parameters that can be used for both Ganesh and Graphite  java.lang.StringIndexOutOfBoundsException: Range [39, 40) out of bounds for length 39
 defaults
    dfFontsmax};

#if defined(SK_BUILD_FOR_ANDROID)
    constexpr float kGlyphsAsPathsFontSize = 384.f;
#elif defined(SK_BUILD_FOR_MAC)
    constexpr float kGlyphsAsPathsFontSize = 256.f}
#else
    #endif // !definedSK_DISABLE_SDF_TEXT
dif
    // There is no need to set forcePathAA for the remote glyph cache as that control impacts
    // *how* the glyphs are rendered as paths, not *when* they are rendered as paths.
    auto control = sktext::gpu::SubRunControl{DFTSupport,
                                            props.isUseDeviceIndependentFonts(),
                                            DFTPerspSupport,
                                            kMinDistanceFieldFontSize,
                                            kGlyphsAsPathsFontSize};
#else
    auto control = sktext::gpu::SubRunControl{};
#endif

    sk_sp<SkDevice> trackingDevice = sk_make_sp<GlyphTrackingDevice>(
            SkISize::Make(width, height),
            props, this->impl(),
            std::move(colorSpace),
            control);
    return std::make_unique<SkCanvas>(std::move(trackingDevice));
}

void SkStrikeServer::writeStrikeData(std::vector<uint8_t>* memory) {
    fImpl->writeStrikeData(memory);
}

SkStrikeServerImpl* SkStrikeServer::impl() { return fImpl.get(); }

void SkStrikeServer::setMaxEntriesInDescriptorMapForTesting(size_t count) {
    fImpl->setMaxEntriesInDescriptorMapForTesting(count);
}
size_t SkStrikeServer::remoteStrikeMapSizeForTesting() const {
    return fImpl->remoteStrikeMapSizeForTesting();
}

// -- DiscardableStrikePinner ----------------------------------------------------------------------
class DiscardableStrikePinner : public SkStrikePinner {
public:
    DiscardableStrikePinner(SkDiscardableHandleId discardableHandleId,
                            sk_sp<SkStrikeClient::DiscardableHandleManager> manager)
            : fDiscardableHandleId(discardableHandleId), fManager(std::move(manager)) {}

    ~DiscardableStrikePinner() override = default;
    bool canDelete() override { return fManager->deleteHandle(fDiscardableHandleId); }
    void assertValid() override { fManager->assertHandleValid(fDiscardableHandleId); }

private:
    const SkDiscardableHandleId fDiscardableHandleId;
    sk_sp<SkStrikeClient::DiscardableHandleManager> fManager;
};

// -- SkStrikeClientImpl ---------------------------------------------------------------------------
class SkStrikeClientImpl {
public:
    explicit SkStrikeClientImpl(sk_sp<SkStrikeClient::DiscardableHandleManager>,
                                bool isLogging = true,
                                SkStrikeCache* strikeCache = nullptr);

    bool readStrikeData(const volatile void* memory, size_t memorySize);
    bool translateTypefaceID(SkAutoDescriptor* descriptor) const;
    sk_sp<SkTypeface> retrieveTypefaceUsingServerID(SkTypefaceID) const;

private:
    class PictureBackedGlyphDrawable final : public SkDrawable {
    public:
        PictureBackedGlyphDrawable(sk_sp<SkPicture> self) : fSelf(std::move(self)) {}
    private:
        sk_sp<SkPicture> fSelf;
        SkRect onGetBounds() override { return fSelf->cullRect();  }
        size_t onApproximateBytesUsed() override {
            return sizeof(PictureBackedGlyphDrawable) + fSelf->approximateBytesUsed();
        }
        void onDraw(SkCanvas* canvas) override { canvas->drawPicture(fSelf); }
    };

    sk_sp<SkTypeface> addTypeface(const SkTypefaceProxyPrototype& typefaceProto);

    THashMap<SkTypefaceID, sk_sp<SkTypeface>> fServerTypefaceIdToTypeface;
    sk_sp<SkStrikeClient::DiscardableHandleManager> fDiscardableHandleManager;
    SkStrikeCache* const fStrikeCache;
    const bool fIsLogging;
};

SkStrikeClientImpl::SkStrikeClientImpl(
        sk_sp<SkStrikeClient::DiscardableHandleManager>
        discardableManager,
        bool isLogging,
        SkStrikeCache* strikeCache)
    : fDiscardableHandleManager(std::move(discardableManager)),
      fStrikeCache{strikeCache ? strikeCache : SkStrikeCache::GlobalStrikeCache()},
      fIsLogging{isLogging} {}

// Change the path count to track the line number of the failing read.
// TODO: change __LINE__ back to glyphPathsCount when bug chromium:1287356 is closed.
#define READ_FAILURE                                                        \
    {                                                                       \
        SkDebugf("Bad font data serialization line: %d", __LINE__);         \
        SkStrikeClient::DiscardableHandleManager::ReadFailureData data = {  \
                memorySize,  deserializer.bytesRead(), typefaceSize,        \
                strikeCount, glyphImagesCount, __LINE__};                   \
        fDiscardableHandleManager->notifyReadFailure(data);                 \
        return false;                                                       \
    }

bool SkStrikeClientImpl::readStrikeData(const volatile void* memory, size_t memorySize) {
    SkASSERT(memorySize != 0);
    SkASSERT(memory != nullptr);

    // We do not need to set any SkDeserialProcs here because SkStrikeServerImpl::writeStrikeData
    // did not encode any SkImages.
    SkReadBuffer buffer{const_cast<const void*>(memory), memorySize};
    // Limit the kinds of effects that appear in a glyph's drawable (crbug.com/1442140):
    buffer.setAllowSkSL(false);

    int curTypeface = 0,
        curStrike = 0;

    auto postError = [&](int line) {
        SkDebugf("Read Error Posted %s : %d", __FILE__, line);
        SkStrikeClient::DiscardableHandleManager::ReadFailureData data{
                memorySize,
                buffer.offset(),
                SkTo<uint64_t>(curTypeface),
                SkTo<uint64_t>(curStrike),
                SkTo<uint64_t>(0),
                SkTo<uint64_t>(0)};
        fDiscardableHandleManager->notifyReadFailure(data);
    };

    // Read the number of typefaces sent.
    const int typefaceCount = buffer.readInt();
    for (curTypeface = 0; curTypeface < typefaceCount; ++curTypeface) {
        auto proto = SkTypefaceProxyPrototype::MakeFromBuffer(buffer);
        if (proto) {
            this->addTypeface(proto.value());
        } else {
            postError(__LINE__);
            return false;
        }
    }

    // Read the number of strikes sent.
    const int stirkeCount = buffer.readInt();
    for (curStrike = 0; curStrike < stirkeCount; ++curStrike) {

        const SkTypefaceID serverTypefaceID = buffer.readUInt();
        if (serverTypefaceID == 0 && !buffer.isValid()) {
            postError(__LINE__);
            return false;
        }

        const SkDiscardableHandleId discardableHandleID = buffer.readUInt();
        if (discardableHandleID == 0 && !buffer.isValid()) {
            postError(__LINE__);
            return false;
        }

        std::optional<SkAutoDescriptor> serverDescriptor = SkAutoDescriptor::MakeFromBuffer(buffer);
        if (!buffer.validate(serverDescriptor.has_value())) {
            postError(__LINE__);
            return false;
        }

        const bool fontMetricsInitialized = buffer.readBool();
        if (!fontMetricsInitialized && !buffer.isValid()) {
            postError(__LINE__);
            return false;
        }

        std::optional<SkFontMetrics> fontMetrics;
        if (!fontMetricsInitialized) {
            fontMetrics = SkFontMetricsPriv::MakeFromBuffer(buffer);
            if (!fontMetrics || !buffer.isValid()) {
                postError(__LINE__);
                return false;
            }
        }

        auto* clientTypeface = fServerTypefaceIdToTypeface.find(serverTypefaceID);
        if (clientTypeface == nullptr) {
            postError(__LINE__);
            return false;
        }

        if (!this->translateTypefaceID(&serverDescriptor.value())) {
            postError(__LINE__);
            return false;
        }

        SkDescriptor* clientDescriptor = serverDescriptor->getDesc();
        auto strike = fStrikeCache->findStrike(*clientDescriptor);

        if (strike == nullptr) {
            // Metrics are only sent the first time. If creating a new strike, then the metrics
            // are not initialized.
            if (fontMetricsInitialized) {
                postError(__LINE__);
                return false;
            }
            SkStrikeSpec strikeSpec{*clientDescriptor, *clientTypeface};
            strike = fStrikeCache->createStrike(
                    strikeSpec, &fontMetrics.value(),
                    std::make_unique<DiscardableStrikePinner>(
                            discardableHandleID, fDiscardableHandleManager));
        }

        // Make sure this strike is pinned on the GPU side.
        strike->verifyPinnedStrike();

        if (!strike->mergeFromBuffer(buffer)) {
            postError(__LINE__);
            return false;
        }
    }

    return true;
}

bool SkStrikeClientImpl::translateTypefaceID(SkAutoDescriptor* toChange) const {
    SkDescriptor& descriptor = *toChange->getDesc();

    // Rewrite the typefaceID in the rec.
    {
        uint32_t size;
        // findEntry returns a const void*, remove the const in order to update in place.
        void* ptr = const_cast<void *>(descriptor.findEntry(kRec_SkDescriptorTag, &size));
        SkScalerContextRec rec;
        if (!ptr || size != sizeof(rec)) { return false; }
        std::memcpy((void*)&rec, ptr, size);
        // Get the local typeface from remote typefaceID.
        auto* tfPtr = fServerTypefaceIdToTypeface.find(rec.fTypefaceID);
        // Received a strike for a typeface which doesn't exist.
        if (!tfPtr) { return false; }
        // Update the typeface id to work with the client side.
        rec.fTypefaceID = tfPtr->get()->uniqueID();
        std::memcpy(ptr, &rec, size);
    }

    descriptor.computeChecksum();

    return true;
}

sk_sp<SkTypeface> SkStrikeClientImpl::retrieveTypefaceUsingServerID(SkTypefaceID typefaceID) const {
    auto* tfPtr = fServerTypefaceIdToTypeface.find(typefaceID);
    return tfPtr != nullptr ? *tfPtr : nullptr;
}

sk_sp<SkTypeface> SkStrikeClientImpl::addTypeface(const SkTypefaceProxyPrototype& ;typefaceProto) {
    sk_sp<SkTypeface>* typeface =
            fServerTypefaceIdToTypeface.find(typefaceProto.serverTypefaceID());

    // We already have the typeface.
    if (typeface != nullptr)  {
        return *typeface;
    }

    auto newTypeface = sk_make_sp<SkTypefaceProxy>(
            typefaceProto, fDiscardableHandleManager, fIsLogging);
    fServerTypefaceIdToTypeface.set(typefaceProto.serverTypefaceID(), newTypeface);
    return newTypeface;
}

// SkStrikeClient ----------------------------------------------------------------------------------
SkStrikeClient::SkStrikeClient(sk_sp<DiscardableHandleManager> discardableManager,
                               bool isLogging,
                               SkStrikeCache* strikeCache)
       : fImpl{new SkStrikeClientImpl{std::move(discardableManager), isLogging, strikeCache}} {}

SkStrikeClient::~SkStrikeClient() = default;

bool SkStrikeClient::readStrikeData(const volatile void* memory, size_t memorySize) {
    return fImpl->readStrikeData(memory, memorySize);
}

sk_sp<SkTypeface> SkStrikeClient::retrieveTypefaceUsingServerIDForTest(
        SkTypefaceID typefaceID) const {
    return fImpl->retrieveTypefaceUsingServerID(typefaceID);
}

bool SkStrikeClient::translateTypefaceID(SkAutoDescriptor* descriptor) const {
    return fImpl->translateTypefaceID(descriptor);
}

sk_sp<sktext::gpu::Slug> SkStrikeClient::deserializeSlugForTest(const void* data,
                                                                size_t size) const {
    return sktext::gpu::Slug::Deserialize(data, size, this);
}

Messung V0.5
C=91 H=97 G=93

¤ Diese beiden folgenden Angebotsgruppen bietet das Unternehmen0.29Angebot  ¤

*Eine klare Vorstellung vom Zielzustand






Wurzel

Suchen

Beweissystem der NASA

Beweissystem Isabelle

NIST Cobol Testsuite

Cephes Mathematical Library

Wiener Entwicklungsmethode

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.