blob: 451589db0a97930a59296fa5754d61d192a74447 [file] [log] [blame]
commit-bot@chromium.orgad854bf2014-05-29 18:46:38 +00001/*
2* Copyright 2014 Google Inc.
3*
4* Use of this source code is governed by a BSD-style license that can be
5* found in the LICENSE file.
6*/
7
8#ifndef GrRectanizer_pow2_DEFINED
9#define GrRectanizer_pow2_DEFINED
10
11#include "GrRectanizer.h"
robertphillipsd5373412014-06-02 10:20:14 -070012#include "SkPoint.h"
commit-bot@chromium.orgad854bf2014-05-29 18:46:38 +000013
robertphillips901e96d2014-06-02 07:15:18 -070014// This Rectanizer quantizes the incoming rects to powers of 2. Each power
15// of two can have, at most, one active row/shelf. Once a row/shelf for
16// a particular power of two gets full its fRows entry is recycled to point
17// to a new row.
18// The skyline algorithm almost always provides a better packing.
commit-bot@chromium.orgad854bf2014-05-29 18:46:38 +000019class GrRectanizerPow2 : public GrRectanizer {
20public:
21 GrRectanizerPow2(int w, int h) : INHERITED(w, h) {
22 this->reset();
23 }
24
25 virtual ~GrRectanizerPow2() { }
26
mtklein36352bf2015-03-25 18:17:31 -070027 void reset() override {
commit-bot@chromium.orgad854bf2014-05-29 18:46:38 +000028 fNextStripY = 0;
29 fAreaSoFar = 0;
30 sk_bzero(fRows, sizeof(fRows));
31 }
32
mtklein36352bf2015-03-25 18:17:31 -070033 bool addRect(int w, int h, SkIPoint16* loc) override;
commit-bot@chromium.orgad854bf2014-05-29 18:46:38 +000034
mtklein36352bf2015-03-25 18:17:31 -070035 float percentFull() const override {
commit-bot@chromium.orgad854bf2014-05-29 18:46:38 +000036 return fAreaSoFar / ((float)this->width() * this->height());
37 }
38
39private:
40 static const int kMIN_HEIGHT_POW2 = 2;
robertphillips901e96d2014-06-02 07:15:18 -070041 static const int kMaxExponent = 16;
commit-bot@chromium.orgad854bf2014-05-29 18:46:38 +000042
43 struct Row {
robertphillipsd5373412014-06-02 10:20:14 -070044 SkIPoint16 fLoc;
robertphillips901e96d2014-06-02 07:15:18 -070045 // fRowHeight is actually known by this struct's position in fRows
46 // but it is used to signal if there exists an open row of this height
commit-bot@chromium.orgad854bf2014-05-29 18:46:38 +000047 int fRowHeight;
48
49 bool canAddWidth(int width, int containerWidth) const {
50 return fLoc.fX + width <= containerWidth;
51 }
52 };
53
robertphillips901e96d2014-06-02 07:15:18 -070054 Row fRows[kMaxExponent]; // 0-th entry will be unused
commit-bot@chromium.orgad854bf2014-05-29 18:46:38 +000055
56 int fNextStripY;
57 int32_t fAreaSoFar;
58
59 static int HeightToRowIndex(int height) {
60 SkASSERT(height >= kMIN_HEIGHT_POW2);
robertphillips901e96d2014-06-02 07:15:18 -070061 int index = 32 - SkCLZ(height - 1);
62 SkASSERT(index < kMaxExponent);
63 return index;
commit-bot@chromium.orgad854bf2014-05-29 18:46:38 +000064 }
65
66 bool canAddStrip(int height) const {
67 return fNextStripY + height <= this->height();
68 }
69
70 void initRow(Row* row, int rowHeight) {
71 row->fLoc.set(0, fNextStripY);
72 row->fRowHeight = rowHeight;
73 fNextStripY += rowHeight;
74 }
75
76 typedef GrRectanizer INHERITED;
77};
78
79#endif