1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/gfx/skia/trunk/src/gpu/GrRectanizer.cpp Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,128 @@ 1.4 + 1.5 +/* 1.6 + * Copyright 2010 Google Inc. 1.7 + * 1.8 + * Use of this source code is governed by a BSD-style license that can be 1.9 + * found in the LICENSE file. 1.10 + */ 1.11 + 1.12 + 1.13 + 1.14 +#include "GrRectanizer.h" 1.15 +#include "GrTBSearch.h" 1.16 + 1.17 +#define MIN_HEIGHT_POW2 2 1.18 + 1.19 +class GrRectanizerPow2 : public GrRectanizer { 1.20 +public: 1.21 + GrRectanizerPow2(int w, int h) : GrRectanizer(w, h) { 1.22 + fNextStripY = 0; 1.23 + fAreaSoFar = 0; 1.24 + sk_bzero(fRows, sizeof(fRows)); 1.25 + } 1.26 + 1.27 + virtual ~GrRectanizerPow2() { 1.28 + } 1.29 + 1.30 + virtual void reset() { 1.31 + fNextStripY = 0; 1.32 + fAreaSoFar = 0; 1.33 + sk_bzero(fRows, sizeof(fRows)); 1.34 + } 1.35 + 1.36 + virtual bool addRect(int w, int h, GrIPoint16* loc); 1.37 + 1.38 + virtual float percentFull() const { 1.39 + return fAreaSoFar / ((float)this->width() * this->height()); 1.40 + } 1.41 + 1.42 + virtual int stripToPurge(int height) const { return -1; } 1.43 + virtual void purgeStripAtY(int yCoord) { } 1.44 + 1.45 + /////////////////////////////////////////////////////////////////////////// 1.46 + 1.47 + struct Row { 1.48 + GrIPoint16 fLoc; 1.49 + int fRowHeight; 1.50 + 1.51 + bool canAddWidth(int width, int containerWidth) const { 1.52 + return fLoc.fX + width <= containerWidth; 1.53 + } 1.54 + }; 1.55 + 1.56 + Row fRows[16]; 1.57 + 1.58 + static int HeightToRowIndex(int height) { 1.59 + SkASSERT(height >= MIN_HEIGHT_POW2); 1.60 + return 32 - SkCLZ(height - 1); 1.61 + } 1.62 + 1.63 + int fNextStripY; 1.64 + int32_t fAreaSoFar; 1.65 + 1.66 + bool canAddStrip(int height) const { 1.67 + return fNextStripY + height <= this->height(); 1.68 + } 1.69 + 1.70 + void initRow(Row* row, int rowHeight) { 1.71 + row->fLoc.set(0, fNextStripY); 1.72 + row->fRowHeight = rowHeight; 1.73 + fNextStripY += rowHeight; 1.74 + } 1.75 +}; 1.76 + 1.77 +bool GrRectanizerPow2::addRect(int width, int height, GrIPoint16* loc) { 1.78 + if ((unsigned)width > (unsigned)this->width() || 1.79 + (unsigned)height > (unsigned)this->height()) { 1.80 + return false; 1.81 + } 1.82 + 1.83 + int32_t area = width * height; 1.84 + 1.85 + /* 1.86 + We use bsearch, but there may be more than one row with the same height, 1.87 + so we actually search for height-1, which can only be a pow2 itself if 1.88 + height == 2. Thus we set a minimum height. 1.89 + */ 1.90 + height = GrNextPow2(height); 1.91 + if (height < MIN_HEIGHT_POW2) { 1.92 + height = MIN_HEIGHT_POW2; 1.93 + } 1.94 + 1.95 + Row* row = &fRows[HeightToRowIndex(height)]; 1.96 + SkASSERT(row->fRowHeight == 0 || row->fRowHeight == height); 1.97 + 1.98 + if (0 == row->fRowHeight) { 1.99 + if (!this->canAddStrip(height)) { 1.100 + return false; 1.101 + } 1.102 + this->initRow(row, height); 1.103 + } else { 1.104 + if (!row->canAddWidth(width, this->width())) { 1.105 + if (!this->canAddStrip(height)) { 1.106 + return false; 1.107 + } 1.108 + // that row is now "full", so retarget our Row record for 1.109 + // another one 1.110 + this->initRow(row, height); 1.111 + } 1.112 + } 1.113 + 1.114 + SkASSERT(row->fRowHeight == height); 1.115 + SkASSERT(row->canAddWidth(width, this->width())); 1.116 + *loc = row->fLoc; 1.117 + row->fLoc.fX += width; 1.118 + 1.119 + SkASSERT(row->fLoc.fX <= this->width()); 1.120 + SkASSERT(row->fLoc.fY <= this->height()); 1.121 + SkASSERT(fNextStripY <= this->height()); 1.122 + fAreaSoFar += area; 1.123 + return true; 1.124 +} 1.125 + 1.126 +/////////////////////////////////////////////////////////////////////////////// 1.127 + 1.128 +// factory is now in GrRectanizer_skyline.cpp 1.129 +//GrRectanizer* GrRectanizer::Factory(int width, int height) { 1.130 +// return SkNEW_ARGS(GrRectanizerPow2, (width, height)); 1.131 +//}