xref: /aosp_15_r20/external/skia/src/gpu/RectanizerPow2.h (revision c8dee2aa9b3f27cf6c858bd81872bdeb2c07ed17)
1*c8dee2aaSAndroid Build Coastguard Worker /*
2*c8dee2aaSAndroid Build Coastguard Worker * Copyright 2014 Google Inc.
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 #ifndef skgpu_RectanizerPow2_DEFINED
9*c8dee2aaSAndroid Build Coastguard Worker #define skgpu_RectanizerPow2_DEFINED
10*c8dee2aaSAndroid Build Coastguard Worker 
11*c8dee2aaSAndroid Build Coastguard Worker #include "include/private/base/SkAssert.h"
12*c8dee2aaSAndroid Build Coastguard Worker #include "include/private/base/SkMalloc.h"
13*c8dee2aaSAndroid Build Coastguard Worker #include "src/base/SkMathPriv.h"
14*c8dee2aaSAndroid Build Coastguard Worker #include "src/core/SkIPoint16.h"
15*c8dee2aaSAndroid Build Coastguard Worker #include "src/gpu/Rectanizer.h"
16*c8dee2aaSAndroid Build Coastguard Worker 
17*c8dee2aaSAndroid Build Coastguard Worker #include <cstdint>
18*c8dee2aaSAndroid Build Coastguard Worker 
19*c8dee2aaSAndroid Build Coastguard Worker namespace skgpu {
20*c8dee2aaSAndroid Build Coastguard Worker 
21*c8dee2aaSAndroid Build Coastguard Worker // This Rectanizer quantizes the incoming rects to powers of 2. Each power
22*c8dee2aaSAndroid Build Coastguard Worker // of two can have, at most, one active row/shelf. Once a row/shelf for
23*c8dee2aaSAndroid Build Coastguard Worker // a particular power of two gets full its fRows entry is recycled to point
24*c8dee2aaSAndroid Build Coastguard Worker // to a new row.
25*c8dee2aaSAndroid Build Coastguard Worker // The skyline algorithm almost always provides a better packing.
26*c8dee2aaSAndroid Build Coastguard Worker //
27*c8dee2aaSAndroid Build Coastguard Worker // Mark this class final in an effort to avoid the vtable when this subclass is used explicitly.
28*c8dee2aaSAndroid Build Coastguard Worker class RectanizerPow2 final : public Rectanizer {
29*c8dee2aaSAndroid Build Coastguard Worker public:
RectanizerPow2(int w,int h)30*c8dee2aaSAndroid Build Coastguard Worker     RectanizerPow2(int w, int h) : Rectanizer(w, h) {
31*c8dee2aaSAndroid Build Coastguard Worker         this->reset();
32*c8dee2aaSAndroid Build Coastguard Worker     }
33*c8dee2aaSAndroid Build Coastguard Worker 
~RectanizerPow2()34*c8dee2aaSAndroid Build Coastguard Worker     ~RectanizerPow2() final {}
35*c8dee2aaSAndroid Build Coastguard Worker 
reset()36*c8dee2aaSAndroid Build Coastguard Worker     void reset() final {
37*c8dee2aaSAndroid Build Coastguard Worker         fNextStripY = 0;
38*c8dee2aaSAndroid Build Coastguard Worker         fAreaSoFar = 0;
39*c8dee2aaSAndroid Build Coastguard Worker         sk_bzero(fRows, sizeof(fRows));
40*c8dee2aaSAndroid Build Coastguard Worker     }
41*c8dee2aaSAndroid Build Coastguard Worker 
42*c8dee2aaSAndroid Build Coastguard Worker     bool addRect(int w, int h, SkIPoint16* loc) final;
43*c8dee2aaSAndroid Build Coastguard Worker 
percentFull()44*c8dee2aaSAndroid Build Coastguard Worker     float percentFull() const final {
45*c8dee2aaSAndroid Build Coastguard Worker         return fAreaSoFar / ((float)this->width() * this->height());
46*c8dee2aaSAndroid Build Coastguard Worker     }
47*c8dee2aaSAndroid Build Coastguard Worker 
48*c8dee2aaSAndroid Build Coastguard Worker private:
49*c8dee2aaSAndroid Build Coastguard Worker     static const int kMIN_HEIGHT_POW2 = 2;
50*c8dee2aaSAndroid Build Coastguard Worker     static const int kMaxExponent = 16;
51*c8dee2aaSAndroid Build Coastguard Worker 
52*c8dee2aaSAndroid Build Coastguard Worker     struct Row {
53*c8dee2aaSAndroid Build Coastguard Worker         SkIPoint16  fLoc;
54*c8dee2aaSAndroid Build Coastguard Worker         // fRowHeight is actually known by this struct's position in fRows
55*c8dee2aaSAndroid Build Coastguard Worker         // but it is used to signal if there exists an open row of this height
56*c8dee2aaSAndroid Build Coastguard Worker         int         fRowHeight;
57*c8dee2aaSAndroid Build Coastguard Worker 
canAddWidthRow58*c8dee2aaSAndroid Build Coastguard Worker         bool canAddWidth(int width, int containerWidth) const {
59*c8dee2aaSAndroid Build Coastguard Worker             return fLoc.fX + width <= containerWidth;
60*c8dee2aaSAndroid Build Coastguard Worker         }
61*c8dee2aaSAndroid Build Coastguard Worker     };
62*c8dee2aaSAndroid Build Coastguard Worker 
63*c8dee2aaSAndroid Build Coastguard Worker     Row fRows[kMaxExponent];    // 0-th entry will be unused
64*c8dee2aaSAndroid Build Coastguard Worker 
65*c8dee2aaSAndroid Build Coastguard Worker     int fNextStripY;
66*c8dee2aaSAndroid Build Coastguard Worker     int32_t fAreaSoFar;
67*c8dee2aaSAndroid Build Coastguard Worker 
HeightToRowIndex(int height)68*c8dee2aaSAndroid Build Coastguard Worker     static int HeightToRowIndex(int height) {
69*c8dee2aaSAndroid Build Coastguard Worker         SkASSERT(height >= kMIN_HEIGHT_POW2);
70*c8dee2aaSAndroid Build Coastguard Worker         int index = 32 - SkCLZ(height - 1);
71*c8dee2aaSAndroid Build Coastguard Worker         SkASSERT(index < kMaxExponent);
72*c8dee2aaSAndroid Build Coastguard Worker         return index;
73*c8dee2aaSAndroid Build Coastguard Worker     }
74*c8dee2aaSAndroid Build Coastguard Worker 
canAddStrip(int height)75*c8dee2aaSAndroid Build Coastguard Worker     bool canAddStrip(int height) const {
76*c8dee2aaSAndroid Build Coastguard Worker         return fNextStripY + height <= this->height();
77*c8dee2aaSAndroid Build Coastguard Worker     }
78*c8dee2aaSAndroid Build Coastguard Worker 
initRow(Row * row,int rowHeight)79*c8dee2aaSAndroid Build Coastguard Worker     void initRow(Row* row, int rowHeight) {
80*c8dee2aaSAndroid Build Coastguard Worker         row->fLoc.set(0, fNextStripY);
81*c8dee2aaSAndroid Build Coastguard Worker         row->fRowHeight = rowHeight;
82*c8dee2aaSAndroid Build Coastguard Worker         fNextStripY += rowHeight;
83*c8dee2aaSAndroid Build Coastguard Worker     }
84*c8dee2aaSAndroid Build Coastguard Worker };
85*c8dee2aaSAndroid Build Coastguard Worker 
86*c8dee2aaSAndroid Build Coastguard Worker } // End of namespace skgpu
87*c8dee2aaSAndroid Build Coastguard Worker 
88*c8dee2aaSAndroid Build Coastguard Worker #endif
89