1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/gfx/skia/trunk/src/gpu/GrRectanizer_fifo.cpp Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,121 @@ 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 GrRectanizerFIFO : public GrRectanizer { 1.20 +public: 1.21 + GrRectanizerFIFO(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 ~GrRectanizerFIFO() { 1.28 + } 1.29 + 1.30 + virtual bool addRect(int w, int h, GrIPoint16* loc); 1.31 + 1.32 + virtual float percentFull() const { 1.33 + return fAreaSoFar / ((float)this->width() * this->height()); 1.34 + } 1.35 + 1.36 + virtual int stripToPurge(int height) const { return -1; } 1.37 + virtual void purgeStripAtY(int yCoord) { } 1.38 + 1.39 + /////////////////////////////////////////////////////////////////////////// 1.40 + 1.41 + struct Row { 1.42 + GrIPoint16 fLoc; 1.43 + int fRowHeight; 1.44 + 1.45 + bool canAddWidth(int width, int containerWidth) const { 1.46 + return fLoc.fX + width <= containerWidth; 1.47 + } 1.48 + }; 1.49 + 1.50 + Row fRows[16]; 1.51 + 1.52 + static int HeightToRowIndex(int height) { 1.53 + SkASSERT(height >= MIN_HEIGHT_POW2); 1.54 + return 32 - Gr_clz(height - 1); 1.55 + } 1.56 + 1.57 + int fNextStripY; 1.58 + int32_t fAreaSoFar; 1.59 + 1.60 + bool canAddStrip(int height) const { 1.61 + return fNextStripY + height <= this->height(); 1.62 + } 1.63 + 1.64 + void initRow(Row* row, int rowHeight) { 1.65 + row->fLoc.set(0, fNextStripY); 1.66 + row->fRowHeight = rowHeight; 1.67 + fNextStripY += rowHeight; 1.68 + } 1.69 +}; 1.70 + 1.71 +bool GrRectanizerFIFO::addRect(int width, int height, GrIPoint16* loc) { 1.72 + if ((unsigned)width > (unsigned)this->width() || 1.73 + (unsigned)height > (unsigned)this->height()) { 1.74 + return false; 1.75 + } 1.76 + 1.77 + int32_t area = width * height; 1.78 + 1.79 + /* 1.80 + We use bsearch, but there may be more than one row with the same height, 1.81 + so we actually search for height-1, which can only be a pow2 itself if 1.82 + height == 2. Thus we set a minimum height. 1.83 + */ 1.84 + height = GrNextPow2(height); 1.85 + if (height < MIN_HEIGHT_POW2) { 1.86 + height = MIN_HEIGHT_POW2; 1.87 + } 1.88 + 1.89 + Row* row = &fRows[HeightToRowIndex(height)]; 1.90 + SkASSERT(row->fRowHeight == 0 || row->fRowHeight == height); 1.91 + 1.92 + if (0 == row->fRowHeight) { 1.93 + if (!this->canAddStrip(height)) { 1.94 + return false; 1.95 + } 1.96 + this->initRow(row, height); 1.97 + } else { 1.98 + if (!row->canAddWidth(width, this->width())) { 1.99 + if (!this->canAddStrip(height)) { 1.100 + return false; 1.101 + } 1.102 + // that row is now "full", so retarget our Row record for 1.103 + // another one 1.104 + this->initRow(row, height); 1.105 + } 1.106 + } 1.107 + 1.108 + SkASSERT(row->fRowHeight == height); 1.109 + SkASSERT(row->canAddWidth(width, this->width())); 1.110 + *loc = row->fLoc; 1.111 + row->fLoc.fX += width; 1.112 + 1.113 + SkASSERT(row->fLoc.fX <= this->width()); 1.114 + SkASSERT(row->fLoc.fY <= this->height()); 1.115 + SkASSERT(fNextStripY <= this->height()); 1.116 + fAreaSoFar += area; 1.117 + return true; 1.118 +} 1.119 + 1.120 +/////////////////////////////////////////////////////////////////////////////// 1.121 + 1.122 +GrRectanizer* GrRectanizer::Factory(int width, int height) { 1.123 + return SkNEW_ARGS(GrRectanizerFIFO, (width, height)); 1.124 +}