xref: /aosp_15_r20/external/skia/src/text/gpu/SlugImpl.cpp (revision c8dee2aa9b3f27cf6c858bd81872bdeb2c07ed17)
1*c8dee2aaSAndroid Build Coastguard Worker /*
2*c8dee2aaSAndroid Build Coastguard Worker  * Copyright 2023 Google LLC
3*c8dee2aaSAndroid Build Coastguard Worker  *
4*c8dee2aaSAndroid Build Coastguard Worker  * Use of this source code is governed by a BSD-style license that can be
5*c8dee2aaSAndroid Build Coastguard Worker  * found in the LICENSE file.
6*c8dee2aaSAndroid Build Coastguard Worker  */
7*c8dee2aaSAndroid Build Coastguard Worker 
8*c8dee2aaSAndroid Build Coastguard Worker #include "src/text/gpu/SlugImpl.h"
9*c8dee2aaSAndroid Build Coastguard Worker 
10*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkMatrix.h"
11*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkPoint.h"
12*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkRect.h"
13*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkSerialProcs.h"
14*c8dee2aaSAndroid Build Coastguard Worker #include "include/private/base/SkAssert.h"
15*c8dee2aaSAndroid Build Coastguard Worker #include "include/private/chromium/Slug.h"
16*c8dee2aaSAndroid Build Coastguard Worker #include "src/core/SkDevice.h"
17*c8dee2aaSAndroid Build Coastguard Worker #include "src/core/SkReadBuffer.h"
18*c8dee2aaSAndroid Build Coastguard Worker #include "src/core/SkWriteBuffer.h"
19*c8dee2aaSAndroid Build Coastguard Worker #include "src/text/GlyphRun.h"
20*c8dee2aaSAndroid Build Coastguard Worker #include "src/text/gpu/SubRunAllocator.h"
21*c8dee2aaSAndroid Build Coastguard Worker #include "src/text/gpu/SubRunContainer.h"
22*c8dee2aaSAndroid Build Coastguard Worker 
23*c8dee2aaSAndroid Build Coastguard Worker #include <memory>
24*c8dee2aaSAndroid Build Coastguard Worker #include <utility>
25*c8dee2aaSAndroid Build Coastguard Worker 
26*c8dee2aaSAndroid Build Coastguard Worker class SkStrikeClient;
27*c8dee2aaSAndroid Build Coastguard Worker 
28*c8dee2aaSAndroid Build Coastguard Worker namespace sktext::gpu {
29*c8dee2aaSAndroid Build Coastguard Worker 
SlugImpl(SubRunAllocator && alloc,gpu::SubRunContainerOwner subRuns,SkRect sourceBounds,SkPoint origin)30*c8dee2aaSAndroid Build Coastguard Worker SlugImpl::SlugImpl(SubRunAllocator&& alloc,
31*c8dee2aaSAndroid Build Coastguard Worker                    gpu::SubRunContainerOwner subRuns,
32*c8dee2aaSAndroid Build Coastguard Worker                    SkRect sourceBounds,
33*c8dee2aaSAndroid Build Coastguard Worker                    SkPoint origin)
34*c8dee2aaSAndroid Build Coastguard Worker         : fAlloc {std::move(alloc)}
35*c8dee2aaSAndroid Build Coastguard Worker         , fSubRuns(std::move(subRuns))
36*c8dee2aaSAndroid Build Coastguard Worker         , fSourceBounds{sourceBounds}
37*c8dee2aaSAndroid Build Coastguard Worker         , fOrigin{origin} {}
38*c8dee2aaSAndroid Build Coastguard Worker 
doFlatten(SkWriteBuffer & buffer) const39*c8dee2aaSAndroid Build Coastguard Worker void SlugImpl::doFlatten(SkWriteBuffer& buffer) const {
40*c8dee2aaSAndroid Build Coastguard Worker     buffer.writeRect(fSourceBounds);
41*c8dee2aaSAndroid Build Coastguard Worker     buffer.writePoint(fOrigin);
42*c8dee2aaSAndroid Build Coastguard Worker     fSubRuns->flattenAllocSizeHint(buffer);
43*c8dee2aaSAndroid Build Coastguard Worker     fSubRuns->flattenRuns(buffer);
44*c8dee2aaSAndroid Build Coastguard Worker }
45*c8dee2aaSAndroid Build Coastguard Worker 
MakeFromBuffer(SkReadBuffer & buffer,const SkStrikeClient * client)46*c8dee2aaSAndroid Build Coastguard Worker sk_sp<Slug> SlugImpl::MakeFromBuffer(SkReadBuffer& buffer, const SkStrikeClient* client) {
47*c8dee2aaSAndroid Build Coastguard Worker     SkRect sourceBounds = buffer.readRect();
48*c8dee2aaSAndroid Build Coastguard Worker     if (!buffer.validate(!sourceBounds.isEmpty())) {
49*c8dee2aaSAndroid Build Coastguard Worker         return nullptr;
50*c8dee2aaSAndroid Build Coastguard Worker     }
51*c8dee2aaSAndroid Build Coastguard Worker     SkPoint origin = buffer.readPoint();
52*c8dee2aaSAndroid Build Coastguard Worker     int allocSizeHint = gpu::SubRunContainer::AllocSizeHintFromBuffer(buffer);
53*c8dee2aaSAndroid Build Coastguard Worker 
54*c8dee2aaSAndroid Build Coastguard Worker     auto [initializer, _, alloc] =
55*c8dee2aaSAndroid Build Coastguard Worker             SubRunAllocator::AllocateClassMemoryAndArena<SlugImpl>(allocSizeHint);
56*c8dee2aaSAndroid Build Coastguard Worker 
57*c8dee2aaSAndroid Build Coastguard Worker     gpu::SubRunContainerOwner container =
58*c8dee2aaSAndroid Build Coastguard Worker             gpu::SubRunContainer::MakeFromBufferInAlloc(buffer, client, &alloc);
59*c8dee2aaSAndroid Build Coastguard Worker 
60*c8dee2aaSAndroid Build Coastguard Worker     // Something went wrong while reading.
61*c8dee2aaSAndroid Build Coastguard Worker     if (!buffer.isValid()) {
62*c8dee2aaSAndroid Build Coastguard Worker         return nullptr;
63*c8dee2aaSAndroid Build Coastguard Worker     }
64*c8dee2aaSAndroid Build Coastguard Worker 
65*c8dee2aaSAndroid Build Coastguard Worker     return sk_sp<SlugImpl>(
66*c8dee2aaSAndroid Build Coastguard Worker             initializer.initialize(std::move(alloc), std::move(container), sourceBounds, origin));
67*c8dee2aaSAndroid Build Coastguard Worker }
68*c8dee2aaSAndroid Build Coastguard Worker 
position_matrix(const SkMatrix & drawMatrix,SkPoint drawOrigin)69*c8dee2aaSAndroid Build Coastguard Worker SkMatrix position_matrix(const SkMatrix& drawMatrix, SkPoint drawOrigin) {
70*c8dee2aaSAndroid Build Coastguard Worker     SkMatrix position_matrix = drawMatrix;
71*c8dee2aaSAndroid Build Coastguard Worker     return position_matrix.preTranslate(drawOrigin.x(), drawOrigin.y());
72*c8dee2aaSAndroid Build Coastguard Worker }
73*c8dee2aaSAndroid Build Coastguard Worker 
Make(const SkMatrix & viewMatrix,const sktext::GlyphRunList & glyphRunList,const SkPaint & paint,SkStrikeDeviceInfo strikeDeviceInfo,sktext::StrikeForGPUCacheInterface * strikeCache)74*c8dee2aaSAndroid Build Coastguard Worker sk_sp<SlugImpl> SlugImpl::Make(const SkMatrix& viewMatrix,
75*c8dee2aaSAndroid Build Coastguard Worker                                const sktext::GlyphRunList& glyphRunList,
76*c8dee2aaSAndroid Build Coastguard Worker                                const SkPaint& paint,
77*c8dee2aaSAndroid Build Coastguard Worker                                SkStrikeDeviceInfo strikeDeviceInfo,
78*c8dee2aaSAndroid Build Coastguard Worker                                sktext::StrikeForGPUCacheInterface* strikeCache) {
79*c8dee2aaSAndroid Build Coastguard Worker     size_t subRunSizeHint = gpu::SubRunContainer::EstimateAllocSize(glyphRunList);
80*c8dee2aaSAndroid Build Coastguard Worker     auto [initializer, _, alloc] =
81*c8dee2aaSAndroid Build Coastguard Worker             SubRunAllocator::AllocateClassMemoryAndArena<SlugImpl>(subRunSizeHint);
82*c8dee2aaSAndroid Build Coastguard Worker 
83*c8dee2aaSAndroid Build Coastguard Worker     const SkMatrix positionMatrix = position_matrix(viewMatrix, glyphRunList.origin());
84*c8dee2aaSAndroid Build Coastguard Worker 
85*c8dee2aaSAndroid Build Coastguard Worker     auto subRuns = gpu::SubRunContainer::MakeInAlloc(glyphRunList,
86*c8dee2aaSAndroid Build Coastguard Worker                                                      positionMatrix,
87*c8dee2aaSAndroid Build Coastguard Worker                                                      paint,
88*c8dee2aaSAndroid Build Coastguard Worker                                                      strikeDeviceInfo,
89*c8dee2aaSAndroid Build Coastguard Worker                                                      strikeCache,
90*c8dee2aaSAndroid Build Coastguard Worker                                                      &alloc,
91*c8dee2aaSAndroid Build Coastguard Worker                                                      gpu::SubRunContainer::kAddSubRuns,
92*c8dee2aaSAndroid Build Coastguard Worker                                                      "Make Slug");
93*c8dee2aaSAndroid Build Coastguard Worker 
94*c8dee2aaSAndroid Build Coastguard Worker     sk_sp<SlugImpl> slug = sk_sp<SlugImpl>(initializer.initialize(std::move(alloc),
95*c8dee2aaSAndroid Build Coastguard Worker                                                                   std::move(subRuns),
96*c8dee2aaSAndroid Build Coastguard Worker                                                                   glyphRunList.sourceBounds(),
97*c8dee2aaSAndroid Build Coastguard Worker                                                                   glyphRunList.origin()));
98*c8dee2aaSAndroid Build Coastguard Worker 
99*c8dee2aaSAndroid Build Coastguard Worker     // There is nothing to draw here. This is particularly a problem with RSX form blobs where a
100*c8dee2aaSAndroid Build Coastguard Worker     // single space becomes a run with no glyphs.
101*c8dee2aaSAndroid Build Coastguard Worker     if (slug->fSubRuns->isEmpty()) { return nullptr; }
102*c8dee2aaSAndroid Build Coastguard Worker 
103*c8dee2aaSAndroid Build Coastguard Worker     return slug;
104*c8dee2aaSAndroid Build Coastguard Worker }
105*c8dee2aaSAndroid Build Coastguard Worker 
AddDeserialProcs(SkDeserialProcs * procs,const SkStrikeClient * client)106*c8dee2aaSAndroid Build Coastguard Worker void Slug::AddDeserialProcs(SkDeserialProcs* procs, const SkStrikeClient* client) {
107*c8dee2aaSAndroid Build Coastguard Worker     SkASSERT(procs);
108*c8dee2aaSAndroid Build Coastguard Worker     procs->fSlugCtx = const_cast<SkStrikeClient*>(client);
109*c8dee2aaSAndroid Build Coastguard Worker     procs->fSlugProc = [](SkReadBuffer& buffer, void* ctx) -> sk_sp<Slug> {
110*c8dee2aaSAndroid Build Coastguard Worker         auto client = static_cast<const SkStrikeClient*>(ctx);
111*c8dee2aaSAndroid Build Coastguard Worker         return SlugImpl::MakeFromBuffer(buffer, client);
112*c8dee2aaSAndroid Build Coastguard Worker     };
113*c8dee2aaSAndroid Build Coastguard Worker }
114*c8dee2aaSAndroid Build Coastguard Worker 
115*c8dee2aaSAndroid Build Coastguard Worker }  // namespace sktext::gpu
116