blob: 296e0520bf4c1796df9ce3d3f7dbf3bd5fc10485 [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"
halcanary4dbbd042016-06-07 17:21:10 -070012#include "SkMathPriv.h"
robertphillipsd5373412014-06-02 10:20:14 -070013#include "SkPoint.h"
commit-bot@chromium.orgad854bf2014-05-29 18:46:38 +000014
robertphillips901e96d2014-06-02 07:15:18 -070015// This Rectanizer quantizes the incoming rects to powers of 2. Each power
16// of two can have, at most, one active row/shelf. Once a row/shelf for
17// a particular power of two gets full its fRows entry is recycled to point
18// to a new row.
19// The skyline algorithm almost always provides a better packing.
commit-bot@chromium.orgad854bf2014-05-29 18:46:38 +000020class GrRectanizerPow2 : public GrRectanizer {
21public:
22 GrRectanizerPow2(int w, int h) : INHERITED(w, h) {
23 this->reset();
24 }
25
26 virtual ~GrRectanizerPow2() { }
27
mtklein36352bf2015-03-25 18:17:31 -070028 void reset() override {
commit-bot@chromium.orgad854bf2014-05-29 18:46:38 +000029 fNextStripY = 0;
30 fAreaSoFar = 0;
31 sk_bzero(fRows, sizeof(fRows));
32 }
33
mtklein36352bf2015-03-25 18:17:31 -070034 bool addRect(int w, int h, SkIPoint16* loc) override;
commit-bot@chromium.orgad854bf2014-05-29 18:46:38 +000035
mtklein36352bf2015-03-25 18:17:31 -070036 float percentFull() const override {
commit-bot@chromium.orgad854bf2014-05-29 18:46:38 +000037 return fAreaSoFar / ((float)this->width() * this->height());
38 }
39
40private:
41 static const int kMIN_HEIGHT_POW2 = 2;
robertphillips901e96d2014-06-02 07:15:18 -070042 static const int kMaxExponent = 16;
commit-bot@chromium.orgad854bf2014-05-29 18:46:38 +000043
44 struct Row {
robertphillipsd5373412014-06-02 10:20:14 -070045 SkIPoint16 fLoc;
robertphillips901e96d2014-06-02 07:15:18 -070046 // fRowHeight is actually known by this struct's position in fRows
47 // but it is used to signal if there exists an open row of this height
commit-bot@chromium.orgad854bf2014-05-29 18:46:38 +000048 int fRowHeight;
49
50 bool canAddWidth(int width, int containerWidth) const {
51 return fLoc.fX + width <= containerWidth;
52 }
53 };
54
robertphillips901e96d2014-06-02 07:15:18 -070055 Row fRows[kMaxExponent]; // 0-th entry will be unused
commit-bot@chromium.orgad854bf2014-05-29 18:46:38 +000056
57 int fNextStripY;
58 int32_t fAreaSoFar;
59
60 static int HeightToRowIndex(int height) {
61 SkASSERT(height >= kMIN_HEIGHT_POW2);
robertphillips901e96d2014-06-02 07:15:18 -070062 int index = 32 - SkCLZ(height - 1);
63 SkASSERT(index < kMaxExponent);
64 return index;
commit-bot@chromium.orgad854bf2014-05-29 18:46:38 +000065 }
66
67 bool canAddStrip(int height) const {
68 return fNextStripY + height <= this->height();
69 }
70
71 void initRow(Row* row, int rowHeight) {
72 row->fLoc.set(0, fNextStripY);
73 row->fRowHeight = rowHeight;
74 fNextStripY += rowHeight;
75 }
76
77 typedef GrRectanizer INHERITED;
78};
79
80#endif