aboutsummaryrefslogtreecommitdiffhomepage
path: root/gpu/include
diff options
context:
space:
mode:
authorGravatar reed@google.com <reed@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81>2010-12-22 21:39:39 +0000
committerGravatar reed@google.com <reed@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81>2010-12-22 21:39:39 +0000
commitac10a2d039c5d52eed66e27cbbc503ab523c1cd5 (patch)
treec5be0c3dd15052016e7d32f376507cb1ea7101dd /gpu/include
parentea8509cd3b1771b36054313d3ccd56679df56044 (diff)
add gpu backend (not hooked up yet)
git-svn-id: http://skia.googlecode.com/svn/trunk@649 2bbb7eff-a529-9590-31e7-b0007b416f81
Diffstat (limited to 'gpu/include')
-rw-r--r--gpu/include/FlingState.h59
-rw-r--r--gpu/include/GrAPI.h37
-rw-r--r--gpu/include/GrAllocPool.h71
-rwxr-xr-xgpu/include/GrAllocator.h230
-rw-r--r--gpu/include/GrAtlas.h88
-rw-r--r--gpu/include/GrClip.h115
-rw-r--r--gpu/include/GrClipIterator.h81
-rw-r--r--gpu/include/GrColor.h72
-rw-r--r--gpu/include/GrConfig.h344
-rw-r--r--gpu/include/GrContext.h322
-rw-r--r--gpu/include/GrDrawTarget.h736
-rw-r--r--gpu/include/GrFontScaler.h43
-rw-r--r--gpu/include/GrGLConfig.h323
-rw-r--r--gpu/include/GrGLIndexBuffer.h53
-rw-r--r--gpu/include/GrGLTexture.h166
-rw-r--r--gpu/include/GrGLVertexBuffer.h55
-rw-r--r--gpu/include/GrGlyph.h89
-rw-r--r--gpu/include/GrGpu.h446
-rw-r--r--gpu/include/GrGpuD3D9.h259
-rw-r--r--gpu/include/GrGpuVertex.h104
-rw-r--r--gpu/include/GrIPoint.h35
-rw-r--r--gpu/include/GrInOrderDrawBuffer.h131
-rw-r--r--gpu/include/GrIndexBuffer.h92
-rw-r--r--gpu/include/GrInstanceCounter.h47
-rw-r--r--gpu/include/GrKey.h47
-rw-r--r--gpu/include/GrMatrix.h370
-rw-r--r--gpu/include/GrMemory.h151
-rw-r--r--gpu/include/GrMesh.h42
-rw-r--r--gpu/include/GrNoncopyable.h38
-rw-r--r--gpu/include/GrPath.h84
-rw-r--r--gpu/include/GrPathIter.h110
-rw-r--r--gpu/include/GrPathSink.h36
-rw-r--r--gpu/include/GrPlotMgr.h84
-rw-r--r--gpu/include/GrPoint.h287
-rw-r--r--gpu/include/GrRandom.h62
-rw-r--r--gpu/include/GrRect.h284
-rw-r--r--gpu/include/GrRectanizer.h64
-rw-r--r--gpu/include/GrRefCnt.h125
-rw-r--r--gpu/include/GrSamplerState.h130
-rw-r--r--gpu/include/GrScalar.h116
-rw-r--r--gpu/include/GrStopwatch.h135
-rw-r--r--gpu/include/GrStringBuilder.h182
-rw-r--r--gpu/include/GrTArray.h298
-rw-r--r--gpu/include/GrTBSearch.h53
-rw-r--r--gpu/include/GrTDArray.h222
-rw-r--r--gpu/include/GrTHashCache.h226
-rw-r--r--gpu/include/GrTLList.h61
-rw-r--r--gpu/include/GrTextContext.h67
-rw-r--r--gpu/include/GrTextStrike.h119
-rw-r--r--gpu/include/GrTexture.h213
-rw-r--r--gpu/include/GrTextureCache.h289
-rw-r--r--gpu/include/GrTouchGesture.h56
-rw-r--r--gpu/include/GrTypes.h142
-rw-r--r--gpu/include/GrUserConfig.h57
-rw-r--r--gpu/include/GrVertexBuffer.h92
-rw-r--r--gpu/include/GrVertexBufferAllocPool.h141
-rw-r--r--gpu/include/SkGpuCanvas.h72
-rw-r--r--gpu/include/SkGr.h238
-rw-r--r--gpu/include/SkGrTexturePixelRef.h50
-rw-r--r--gpu/include/SkUIView.h64
60 files changed, 8805 insertions, 0 deletions
diff --git a/gpu/include/FlingState.h b/gpu/include/FlingState.h
new file mode 100644
index 0000000000..a1da4fbc86
--- /dev/null
+++ b/gpu/include/FlingState.h
@@ -0,0 +1,59 @@
+/*
+ Copyright 2010 Google Inc.
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ */
+
+
+#ifndef SkFlingState_DEFINED
+#define SkFlingState_DEFINED
+
+#include "SkScalar.h"
+#include "SkPoint.h"
+
+class SkMatrix;
+
+struct FlingState {
+ FlingState() : fActive(false) {}
+
+ bool isActive() const { return fActive; }
+ void stop() { fActive = false; }
+
+ void reset(float sx, float sy);
+ bool evaluateMatrix(SkMatrix* matrix);
+
+private:
+ SkPoint fDirection;
+ SkScalar fSpeed0;
+ double fTime0;
+ bool fActive;
+};
+
+class GrAnimateFloat {
+public:
+ GrAnimateFloat();
+
+ void start(float v0, float v1, float duration);
+ bool isActive() const { return fTime0 != 0; }
+ void stop() { fTime0 = 0; }
+
+ float evaluate();
+
+private:
+ float fValue0, fValue1, fDuration;
+ SkMSec fTime0;
+};
+
+#endif
+
+
diff --git a/gpu/include/GrAPI.h b/gpu/include/GrAPI.h
new file mode 100644
index 0000000000..b660e8d869
--- /dev/null
+++ b/gpu/include/GrAPI.h
@@ -0,0 +1,37 @@
+
+
+class GrAPI {
+public:
+
+ void setRenderTarget(GrRenderTarget* target);
+
+ void setMatrix(const GrMatrix&);
+
+ void setClip(rect, bool aa);
+ void setClip(rect[], bool aa);
+ void setClip(path, bool aa);
+ void setClip(rect, texture/key, state, matrix);
+ void setClip(path, texture/key, state, matrix);
+
+ void setColor(color);
+ void setTexture(texture/key, sampler, const GrMatrix* = NULL);
+ void setBlend(src, dst);
+
+ void drawRect(const GrRect&, stroke, join);
+ void drawOval(const GrRect&, stroke);
+ void drawRoundRect(const GrRect&, GrScalar ovalW, GrScalar ovalH, stroke);
+ void drawPath(const GrPathIter&, GrPathFill);
+ void drawVertices(...);
+ void drawGlyphs(const uint16_t[], int count, const GrPoint[], GrFontScaler*);
+
+///
+
+ void save();
+ void restore();
+ void concatMatrix(const GrMatrix&);
+ void concatClipRect(const GrRect&);
+ void concatClipPath(const GrPathIter&, bool aa);
+
+};
+
+
diff --git a/gpu/include/GrAllocPool.h b/gpu/include/GrAllocPool.h
new file mode 100644
index 0000000000..46359e5058
--- /dev/null
+++ b/gpu/include/GrAllocPool.h
@@ -0,0 +1,71 @@
+/*
+ Copyright 2010 Google Inc.
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ */
+
+
+#ifndef GrAllocPool_DEFINED
+#define GrAllocPool_DEFINED
+
+#include "GrNoncopyable.h"
+
+class GrAllocPool : GrNoncopyable {
+public:
+ GrAllocPool(size_t blockSize = 0);
+ ~GrAllocPool();
+
+ /**
+ * Frees all blocks that have been allocated with alloc().
+ */
+ void reset();
+
+ /**
+ * Returns a block of memory bytes size big. This address must not be
+ * passed to realloc/free/delete or any other function that assumes the
+ * address was allocated by malloc or new (becuase it hasn't).
+ */
+ void* alloc(size_t bytes);
+
+ /**
+ * Releases the most recently allocated bytes back to allocpool.
+ */
+ void release(size_t bytes);
+
+private:
+ struct Block;
+
+ Block* fBlock;
+ size_t fMinBlockSize;
+
+#if GR_DEBUG
+ int fBlocksAllocated;
+ void validate() const;
+#else
+ void validate() const {}
+#endif
+};
+
+template <typename T> class GrTAllocPool {
+public:
+ GrTAllocPool(int count) : fPool(count * sizeof(T)) {}
+
+ void reset() { fPool.reset(); }
+ T* alloc() { return (T*)fPool.alloc(sizeof(T)); }
+
+private:
+ GrAllocPool fPool;
+};
+
+#endif
+
diff --git a/gpu/include/GrAllocator.h b/gpu/include/GrAllocator.h
new file mode 100755
index 0000000000..da02ba40b0
--- /dev/null
+++ b/gpu/include/GrAllocator.h
@@ -0,0 +1,230 @@
+/*
+ Copyright 2010 Google Inc.
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ */
+
+
+#ifndef GrAllocator_DEFINED
+#define GrAllocator_DEFINED
+
+#include "GrConfig.h"
+#include "GrTArray.h"
+
+class GrAllocator {
+public:
+ virtual ~GrAllocator() {
+ reset();
+ }
+
+ /**
+ * Create an allocator
+ *
+ * @param itemSize the size of each item to allocate
+ * @param itemsPerBlock the number of items to allocate at once
+ * @param initialBlock optional memory to use for the first block.
+ * Must be at least itemSize*itemsPerBlock sized.
+ * Caller is responsible for freeing this memory.
+ */
+ GrAllocator(size_t itemSize, uint32_t itemsPerBlock, void* initialBlock) :
+ fBlocks(fBlockInitialStorage, NUM_INIT_BLOCK_PTRS),
+ fItemSize(itemSize),
+ fItemsPerBlock(itemsPerBlock),
+ fOwnFirstBlock(NULL == initialBlock),
+ fCount(0) {
+ fBlockSize = fItemSize * fItemsPerBlock;
+ fBlocks.push_back() = initialBlock;
+ GR_DEBUGCODE(if (!fOwnFirstBlock) {*((char*)initialBlock+fBlockSize-1)='a';} );
+ }
+
+ /**
+ * Adds an item and returns pointer to it.
+ *
+ * @return pointer to the added item.
+ */
+ void* push_back() {
+ uint32_t indexInBlock = fCount % fItemsPerBlock;
+ // we always have at least one block
+ if (0 == indexInBlock) {
+ if (0 != fCount) {
+ fBlocks.push_back() = GrMalloc(fBlockSize);
+ } else if (fOwnFirstBlock) {
+ fBlocks[0] = GrMalloc(fBlockSize);
+ }
+ }
+ void* ret = (char*)fBlocks[fCount/fItemsPerBlock] +
+ fItemSize * indexInBlock;
+ ++fCount;
+ return ret;
+ }
+
+ /**
+ * removes all added items
+ */
+ void reset() {
+ uint32_t blockCount = GrMax((unsigned)1,
+ GrUIDivRoundUp(fCount, fItemsPerBlock));
+ for (uint32_t i = 1; i < blockCount; ++i) {
+ GrFree(fBlocks[i]);
+ }
+ if (fOwnFirstBlock) {
+ GrFree(fBlocks[0]);
+ fBlocks[0] = NULL;
+ }
+ fBlocks.pop_back_n(blockCount-1);
+ fCount = 0;
+ }
+
+ /**
+ * count of items
+ */
+ uint32_t count() const {
+ return fCount;
+ }
+
+ /**
+ * is the count 0
+ */
+ bool empty() const { return fCount == 0; }
+
+ /**
+ * access last item, only call if count() != 0
+ */
+ void* back() {
+ GrAssert(fCount);
+ return (*this)[fCount-1];
+ }
+
+ /**
+ * access last item, only call if count() != 0
+ */
+ const void* back() const {
+ GrAssert(fCount);
+ return (*this)[fCount-1];
+ }
+
+ /**
+ * access item by index.
+ */
+ void* operator[] (uint32_t i) {
+ GrAssert(i < fCount);
+ return (char*)fBlocks[i / fItemsPerBlock] +
+ fItemSize * (i % fItemsPerBlock);
+ }
+
+ /**
+ * access item by index.
+ */
+ const void* operator[] (uint32_t i) const {
+ GrAssert(i < fCount);
+ return (const char*)fBlocks[i / fItemsPerBlock] +
+ fItemSize * (i % fItemsPerBlock);
+ }
+
+private:
+ static const uint32_t NUM_INIT_BLOCK_PTRS = 8;
+
+ GrTArray<void*> fBlocks;
+ size_t fBlockSize;
+ char fBlockInitialStorage[NUM_INIT_BLOCK_PTRS*sizeof(void*)];
+ size_t fItemSize;
+ uint32_t fItemsPerBlock;
+ bool fOwnFirstBlock;
+ uint32_t fCount;
+};
+
+template <typename T>
+class GrTAllocator {
+private:
+ GrAllocator fAllocator;
+
+public:
+ virtual ~GrTAllocator() {};
+
+ /**
+ * Create an allocator
+ *
+ * @param itemsPerBlock the number of items to allocate at once
+ * @param initialBlock optional memory to use for the first block.
+ * Must be at least size(T)*itemsPerBlock sized.
+ * Caller is responsible for freeing this memory.
+ */
+ GrTAllocator(uint32_t itemsPerBlock, void* initialBlock) :
+ fAllocator(sizeof(T), itemsPerBlock, initialBlock)
+ {}
+
+ /**
+ * Adds an item and returns it.
+ *
+ * @return the added item.
+ */
+ T& push_back() {
+ void* item = fAllocator.push_back();
+ GrAssert(NULL != item);
+ new (item) T;
+ return *(T*)item;
+ }
+
+ /**
+ * removes all added items
+ */
+ void reset() {
+ uint32_t c = fAllocator.count();
+ for (uint32_t i = 0; i < c; ++i) {
+ ((T*)fAllocator[i])->~T();
+ }
+ fAllocator.reset();
+ }
+
+ /**
+ * count of items
+ */
+ uint32_t count() const {
+ return fAllocator.count();
+ }
+
+ /**
+ * is the count 0
+ */
+ bool empty() const { return fAllocator.empty(); }
+
+ /**
+ * access last item, only call if count() != 0
+ */
+ T& back() {
+ return *(T*)fAllocator.back();
+ }
+
+ /**
+ * access last item, only call if count() != 0
+ */
+ const T& back() const {
+ return *(const T*)fAllocator.back();
+ }
+
+ /**
+ * access item by index.
+ */
+ T& operator[] (uint32_t i) {
+ return *(T*)(fAllocator[i]);
+ }
+
+ /**
+ * access item by index.
+ */
+ const T& operator[] (uint32_t i) const {
+ return *(const T*)(fAllocator[i]);
+ }
+};
+
+#endif
diff --git a/gpu/include/GrAtlas.h b/gpu/include/GrAtlas.h
new file mode 100644
index 0000000000..9526e0bb4c
--- /dev/null
+++ b/gpu/include/GrAtlas.h
@@ -0,0 +1,88 @@
+/*
+ Copyright 2010 Google Inc.
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ */
+
+
+#ifndef GrAtlas_DEFINED
+#define GrAtlas_DEFINED
+
+#include "GrPoint.h"
+#include "GrTexture.h"
+#include "GrTDArray.h"
+
+class GrGpu;
+class GrRectanizer;
+class GrAtlasMgr;
+
+class GrAtlas {
+public:
+ GrAtlas(GrAtlasMgr*, int plotX, int plotY);
+
+ int getPlotX() const { return fPlot.fX; }
+ int getPlotY() const { return fPlot.fY; }
+
+ GrTexture* texture() const { return fTexture; }
+
+ bool addSubImage(int width, int height, const void*, GrIPoint16*);
+
+ static void FreeLList(GrAtlas* atlas) {
+ while (atlas) {
+ GrAtlas* next = atlas->fNext;
+ delete atlas;
+ atlas = next;
+ }
+ }
+
+ // testing
+ GrAtlas* nextAtlas() const { return fNext; }
+
+private:
+ ~GrAtlas(); // does not try to delete the fNext field
+
+ GrAtlas* fNext;
+ GrTexture* fTexture;
+ GrRectanizer* fRects;
+ GrAtlasMgr* fAtlasMgr;
+ GrIPoint16 fPlot;
+
+ friend class GrAtlasMgr;
+};
+
+class GrPlotMgr;
+
+class GrAtlasMgr {
+public:
+ GrAtlasMgr(GrGpu*);
+ ~GrAtlasMgr();
+
+ GrAtlas* addToAtlas(GrAtlas*, int width, int height, const void*,
+ GrIPoint16*);
+
+ GrTexture* getTexture() const { return fTexture; }
+
+ // to be called by ~GrAtlas()
+ void freePlot(int x, int y);
+
+ void abandonAll();
+
+private:
+ GrGpu* fGpu;
+ GrTexture* fTexture;
+ GrPlotMgr* fPlotMgr;
+};
+
+#endif
+
+
diff --git a/gpu/include/GrClip.h b/gpu/include/GrClip.h
new file mode 100644
index 0000000000..8e3030c753
--- /dev/null
+++ b/gpu/include/GrClip.h
@@ -0,0 +1,115 @@
+/*
+ Copyright 2010 Google Inc.
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ */
+
+
+#ifndef GrClip_DEFINED
+#define GrClip_DEFINED
+
+#include "GrClipIterator.h"
+#include "GrRect.h"
+#include "GrTDArray.h"
+
+class GrClip {
+public:
+ GrClip();
+ GrClip(const GrClip& src);
+ GrClip(GrClipIterator* iter);
+ ~GrClip();
+
+ GrClip& operator=(const GrClip& src);
+
+ bool isEmpty() const { return fBounds.isEmpty(); }
+ bool isComplex() const { return fList.count() > 0; }
+ bool isRect() const {
+ return !this->isEmpty() && !this->isComplex();
+ }
+
+ const GrIRect& getBounds() const { return fBounds; }
+
+ /**
+ * Resets this clip to be empty (fBounds is empty, and fList is empty)
+ */
+ void setEmpty();
+
+ /**
+ * Resets this clip to have fBounds == rect, and fList is empty.
+ */
+ void setRect(const GrIRect& rect);
+
+ /**
+ * Append a rect to an existing clip. The call must ensure that rect does
+ * not overlap with any previous rect in this clip (either from setRect
+ * or addRect). fBounds is automatically updated to reflect the union of
+ * all rects that have been added.
+ */
+ void addRect(const GrIRect&);
+
+ void setFromIterator(GrClipIterator* iter);
+
+ friend bool operator==(const GrClip& a, const GrClip& b) {
+ return a.fBounds == b.fBounds && a.fList == b.fList;
+ }
+ friend bool operator!=(const GrClip& a, const GrClip& b) {
+ return !(a == b);
+ }
+
+ /**
+ * Return the number of rects in this clip: 0 for empty, 1 for a rect,
+ * or N for a complex clip.
+ */
+ int countRects() const {
+ return this->isEmpty() ? 0 : GrMax<int>(1, fList.count());
+ }
+
+ /**
+ * Return an array of rects for this clip. Use countRects() to know the
+ * number of entries.
+ */
+ const GrIRect* getRects() const {
+ return fList.count() > 0 ? fList.begin() : &fBounds;
+ }
+
+#if GR_DEBUG
+ void validate() const;
+#else
+ void validate() const {}
+#endif
+
+private:
+ GrTDArray<GrIRect> fList;
+ GrIRect fBounds;
+};
+
+class GrClipIter : public GrClipIterator {
+public:
+ GrClipIter(const GrClip& clip) : fClip(&clip), fIndex(0) {}
+ GrClipIter() : fClip(NULL), fIndex(0) {}
+
+ void reset(const GrClip& clip);
+
+ virtual bool isDone();
+ virtual void rewind();
+ virtual void getRect(GrIRect* r);
+ virtual void next();
+ virtual void computeBounds(GrIRect* r);
+
+private:
+ const GrClip* fClip;
+ int fIndex;
+};
+
+#endif
+
diff --git a/gpu/include/GrClipIterator.h b/gpu/include/GrClipIterator.h
new file mode 100644
index 0000000000..d1fe4dde2f
--- /dev/null
+++ b/gpu/include/GrClipIterator.h
@@ -0,0 +1,81 @@
+/*
+ Copyright 2010 Google Inc.
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ */
+
+
+#ifndef GrClipIterator_DEFINED
+#define GrClipIterator_DEFINED
+
+#include "GrRect.h"
+
+class GrClipIterator {
+public:
+ GrClipIterator() : fNeedBounds(true) {}
+ virtual ~GrClipIterator() {}
+
+ /**
+ * Returns true if there are no more rects to process
+ */
+ virtual bool isDone() = 0;
+
+ /**
+ * Rewind the iterate to replay the set of rects again
+ */
+ virtual void rewind() = 0;
+
+ /**
+ * Return the current rect. It is an error to call this when done() is true
+ */
+ virtual void getRect(GrIRect*) = 0;
+
+ /**
+ * Call to move to the next rect in the set
+ */
+ virtual void next() = 0;
+
+ /**
+ * Set bounds to be the bounds of the clip.
+ */
+ virtual void computeBounds(GrIRect* bounds) = 0;
+
+ /**
+ * Subclass should call this whenever their underlying bounds has changed.
+ */
+ void invalidateBoundsCache() { fNeedBounds = true; }
+
+ const GrIRect& getBounds() {
+ if (fNeedBounds) {
+ this->computeBounds(&fBounds);
+ fNeedBounds = false;
+ }
+ return fBounds;
+ }
+
+private:
+ GrIRect fBounds;
+ bool fNeedBounds;
+};
+
+/**
+ * Call to rewind iter, first checking to see if iter is NULL
+ */
+static inline void GrSafeRewind(GrClipIterator* iter) {
+ if (iter) {
+ iter->rewind();
+ }
+}
+
+#endif
+
diff --git a/gpu/include/GrColor.h b/gpu/include/GrColor.h
new file mode 100644
index 0000000000..8dc03d258c
--- /dev/null
+++ b/gpu/include/GrColor.h
@@ -0,0 +1,72 @@
+/*
+ Copyright 2010 Google Inc.
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ */
+
+
+#ifndef GrColor_DEFINED
+#define GrColor_DEFINED
+
+#include "GrTypes.h"
+
+/**
+ * GrColor is 4 bytes for R, G, B, A, in a compile-time specific order. The
+ * components are stored premultiplied.
+ */
+typedef uint32_t GrColor;
+
+// indices for address a GrColor as an array of bytes
+
+#define GrColor_INDEX_R 0
+#define GrColor_INDEX_G 1
+#define GrColor_INDEX_B 2
+#define GrColor_INDEX_A 3
+
+// shfit amount to assign a component to a GrColor int
+
+#define GrColor_SHIFT_R 0
+#define GrColor_SHIFT_G 8
+#define GrColor_SHIFT_B 16
+#define GrColor_SHIFT_A 24
+
+/**
+ * Pack 4 components (RGBA) into a GrColor int
+ */
+static inline GrColor GrColorPackRGBA(unsigned r, unsigned g,
+ unsigned b, unsigned a) {
+ GrAssert((uint8_t)r == r);
+ GrAssert((uint8_t)g == g);
+ GrAssert((uint8_t)b == b);
+ GrAssert((uint8_t)a == a);
+ return (r << GrColor_SHIFT_R) |
+ (g << GrColor_SHIFT_G) |
+ (b << GrColor_SHIFT_B) |
+ (a << GrColor_SHIFT_A);
+}
+
+// extract a component (byte) from a GrColor int
+
+#define GrColorUnpackR(color) (((color) >> GrColor_SHIFT_R) & 0xFF)
+#define GrColorUnpackG(color) (((color) >> GrColor_SHIFT_G) & 0xFF)
+#define GrColorUnpackB(color) (((color) >> GrColor_SHIFT_B) & 0xFF)
+#define GrColorUnpackA(color) (((color) >> GrColor_SHIFT_A) & 0xFF)
+
+/**
+ * Since premultiplied means that alpha >= color, we construct a color with
+ * each component==255 and alpha == 0 to be "illegal"
+ */
+#define GrColor_ILLEGAL (~(0xFF << GrColor_SHIFT_A))
+
+#endif
+
diff --git a/gpu/include/GrConfig.h b/gpu/include/GrConfig.h
new file mode 100644
index 0000000000..9c18f60ef6
--- /dev/null
+++ b/gpu/include/GrConfig.h
@@ -0,0 +1,344 @@
+/*
+ Copyright 2010 Google Inc.
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ */
+
+
+#ifndef GrConfig_DEFINED
+#define GrConfig_DEFINED
+
+///////////////////////////////////////////////////////////////////////////////
+// preconfig section:
+//
+// All the work before including GrUserConfig.h should center around guessing
+// what platform we're on, and defining low-level symbols based on that.
+//
+// A build environment may have already defined symbols, so we first check
+// for that
+//
+
+// hack to ensure we know what sort of Apple platform we're on
+#if defined(__APPLE_CPP__) || defined(__APPLE_CC__)
+ #include <TargetConditionals.h>
+#endif
+
+/**
+ * Gr defines are set to 0 or 1, rather than being undefined or defined
+ */
+
+#if !defined(GR_ANDROID_BUILD)
+ #define GR_ANDROID_BUILD 0
+#endif
+#if !defined(GR_IOS_BUILD)
+ #define GR_IOS_BUILD 0
+#endif
+#if !defined(GR_LINUX_BUILD)
+ #define GR_LINUX_BUILD 0
+#endif
+#if !defined(GR_MAC_BUILD)
+ #define GR_MAC_BUILD 0
+#endif
+#if !defined(GR_WIN32_BUILD)
+ #define GR_WIN32_BUILD 0
+#endif
+#if !defined(GR_QNX_BUILD)
+ #define GR_QNX_BUILD 0
+#endif
+
+/**
+ * If no build target has been defined, attempt to infer.
+ */
+#if !GR_ANDROID_BUILD && !GR_IOS_BUILD && !GR_LINUX_BUILD && !GR_MAC_BUILD && !GR_WIN32_BUILD && !GR_QNX_BUILD
+ #if defined(_WIN32)
+ #undef GR_WIN32_BUILD
+ #define GR_WIN32_BUILD 1
+// #error "WIN"
+ #elif TARGET_OS_IPHONE || TARGET_IPHONE_SIMULATOR
+ #undef GR_IOS_BUILD
+ #define GR_IOS_BUILD 1
+// #error "IOS"
+ #elif ANDROID_NDK || defined(ANDROID)
+ #undef GR_ANDROID_BUILD
+ #define GR_ANDROID_BUILD 1
+// #error "ANDROID"
+ #elif TARGET_OS_MAC
+ #undef GR_MAC_BUILD
+ #define GR_MAC_BUILD 1
+// #error "MAC"
+ #elif TARGET_OS_QNX || defined(__QNXNTO__)
+ #undef GR_QNX_BUILD
+ #define GR_QNX_BUILD 1
+// #error "QNX"
+ #else
+ #undef GR_LINUX_BUILD
+ #define GR_LINUX_BUILD 1
+// #error "LINUX"
+ #endif
+#endif
+
+#if !defined(GR_DEBUG) && !defined(GR_RELEASE)
+ #ifdef NDEBUG
+ #define GR_DEBUG 0
+ #else
+ #define GR_DEBUG 1
+ #endif
+ #define GR_RELEASE !GR_DEBUG
+#endif
+
+///////////////////////////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////////////////////////
+
+/*
+ * Pull stdint.h in before user-config, to be sure our __STDC... macros are
+ * defined before anyone else might try to include stdint.h
+ */
+#define __STDC_LIMIT_MACROS
+#define __STDC_CONSTANT_MACROS
+#include <stdint.h>
+
+/*
+ * The "user config" file can be empty, and everything should work. It is
+ * meant to store a given platform/client's overrides of our guess-work.
+ *
+ * A alternate user config file can be specified by defining
+ * GR_USER_CONFIG_FILE. It should be defined relative to GrConfig.h
+ *
+ * e.g. it can specify GR_DEBUG/GR_RELEASE as it please, change the BUILD
+ * target, or supply its own defines for anything else (e.g. GR_SCALAR)
+ */
+#if !defined(GR_USER_CONFIG_FILE)
+ #include "GrUserConfig.h"
+#else
+ #include GR_USER_CONFIG_FILE
+#endif
+
+
+///////////////////////////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////////////////////////
+// postconfig section:
+//
+// By now we must have a GR_..._BUILD symbol set to 1, and a decision about
+// debug -vs- release
+//
+
+extern void GrPrintf(const char format[], ...);
+
+/**
+ * GR_STRING makes a string of X where X is expanded before conversion to a string
+ * if X itself contains macros.
+ */
+#define GR_STRING(X) GR_STRING_IMPL(X)
+#define GR_STRING_IMPL(X) #X
+
+/**
+ * GR_CONCAT concatenates X and Y where each is expanded before
+ * contanenation if either contains macros.
+ */
+#define GR_CONCAT(X,Y) GR_CONCAT_IMPL(X,Y)
+#define GR_CONCAT_IMPL(X,Y) X##Y
+
+/**
+ * Creates a string of the form "<filename>(<linenumber>) : "
+ */
+#define GR_FILE_AND_LINE_STR __FILE__ "(" GR_STRING(__LINE__) ") : "
+
+/**
+ * Compilers have different ways of issuing warnings. This macro
+ * attempts to abstract them, but may need to be specialized for your
+ * particular compiler.
+ * To insert compiler warnings use "#pragma message GR_WARN(<string>)"
+ */
+#if _MSC_VER
+ #define GR_WARN(MSG) (GR_FILE_AND_LINE_STR "WARNING: " MSG)
+#else//__GNUC__ - may need other defines for different compilers
+ #define GR_WARN(MSG) ("WARNING: " MSG)
+#endif
+
+/**
+ * GR_ALWAYSBREAK is an unconditional break in all builds.
+ */
+#if !defined(GR_ALWAYSBREAK)
+ #if GR_WIN32_BUILD
+ #define GR_ALWAYSBREAK __debugbreak()
+ #else
+ // TODO: do other platforms really not have continuable breakpoints?
+ // sign extend for 64bit architectures to be sure this is
+ // in the high address range
+ #define GR_ALWAYSBREAK *((int*)(int64_t)(int32_t)0xbeefcafe) = 0;
+ #endif
+#endif
+
+/**
+ * GR_DEBUGBREAK is an unconditional break in debug builds.
+ */
+#if !defined(GR_DEBUGBREAK)
+ #if GR_DEBUG
+ #define GR_DEBUGBREAK GR_ALWAYSBREAK
+ #else
+ #define GR_DEBUGBREAK
+ #endif
+#endif
+
+/**
+ * GR_ALWAYSASSERT is an assertion in all builds.
+ */
+#if !defined(GR_ALWAYSASSERT)
+ #define GR_ALWAYSASSERT(COND) \
+ do { \
+ if (!(COND)) { \
+ GrPrintf("%s %s failed\n", GR_FILE_AND_LINE_STR, #COND); \
+ GR_ALWAYSBREAK; \
+ } \
+ } while (false)
+#endif
+
+/**
+ * GR_DEBUGASSERT is an assertion in debug builds only.
+ */
+#if !defined(GR_DEBUGASSERT)
+ #if GR_DEBUG
+ #define GR_DEBUGASSERT(COND) GR_ALWAYSASSERT(COND)
+ #else
+ #define GR_DEBUGASSERT(COND)
+ #endif
+#endif
+
+/**
+ * Prettier forms of the above macros.
+ */
+#define GrAssert(COND) GR_DEBUGASSERT(COND)
+#define GrAlwaysAssert(COND) GR_ALWAYSASSERT(COND)
+
+/**
+ * GR_DEBUGCODE compiles the code X in debug builds only
+ */
+#if !defined(GR_DEBUGCODE)
+ #if GR_DEBUG
+ #define GR_DEBUGCODE(X) X
+ #else
+ #define GR_DEBUGCODE(X)
+ #endif
+#endif
+
+/**
+ * GR_STATIC_ASSERT is a compile time assertion. Depending on the platform
+ * it may print the message in the compiler log. Obviously, the condition must
+ * be evaluatable at compile time.
+ */
+// VS 2010 and GCC compiled with c++0x or gnu++0x support the new
+// static_assert.
+#if !defined(GR_STATIC_ASSERT)
+ #if (_MSC_VER >= 1600) || __GXX_EXPERIMENTAL_CXX0X__
+ #define GR_STATIC_ASSERT(CONDITION) static_assert(CONDITION, "bug")
+ #else
+ template <bool> class GR_STATIC_ASSERT_FAILURE;
+ template <> class GR_STATIC_ASSERT_FAILURE<true> {};
+ #define GR_STATIC_ASSERT(CONDITION) \
+ enum {GR_CONCAT(X,__LINE__) = \
+ sizeof(GR_STATIC_ASSERT_FAILURE<CONDITION>)}
+ #endif
+#endif
+
+#if !defined(GR_SCALAR_IS_FLOAT)
+ #define GR_SCALAR_IS_FLOAT 0
+#endif
+#if !defined(GR_SCALAR_IS_FIXED)
+ #define GR_SCALAR_IS_FIXED 0
+#endif
+
+#if !defined(GR_TEXT_SCALAR_TYPE_IS_USHORT)
+ #define GR_TEXT_SCALAR_TYPE_IS_USHORT 0
+#endif
+#if !defined(GR_TEXT_SCALAR_TYPE_IS_FLOAT)
+ #define GR_TEXT_SCALAR_TYPE_IS_FLOAT 0
+#endif
+#if !defined(GR_TEXT_SCALAR_TYPE_IS_FIXED)
+ #define GR_TEXT_SCALAR_TYPE_IS_FIXED 0
+#endif
+
+#ifndef GR_DUMP_TEXTURE_UPLOAD
+ #define GR_DUMP_TEXTURE_UPLOAD 0
+#endif
+
+/**
+ * GR_COLLECT_STATS controls whether the GrGpu class collects stats.
+ * If not already defined then collect in debug build but not release.
+ */
+#if !defined(GR_COLLECT_STATS)
+ #define GR_COLLECT_STATS GR_DEBUG
+#endif
+
+/**
+ * GR_GL_LOG_CALLS controls whether each GL call is logged.
+ */
+#if !defined(GR_GL_LOG_CALLS)
+ #define GR_GL_LOG_CALLS 0
+#endif
+
+///////////////////////////////////////////////////////////////////////////////
+// tail section:
+//
+// Now we just assert if we are missing some required define, or if we detect
+// and inconsistent combination of defines
+//
+
+
+/**
+ * Only one build target macro should be 1 and the rest should be 0.
+ */
+#define GR_BUILD_SUM (GR_WIN32_BUILD + GR_MAC_BUILD + GR_IOS_BUILD + GR_ANDROID_BUILD + GR_LINUX_BUILD + GR_QNX_BUILD)
+#if 0 == GR_BUILD_SUM
+ #error "Missing a GR_BUILD define"
+#elif 1 != GR_BUILD_SUM
+ #error "More than one GR_BUILD defined"
+#endif
+
+
+#if !GR_SCALAR_IS_FLOAT && !GR_SCALAR_IS_FIXED
+ #undef GR_SCALAR_IS_FLOAT
+ #define GR_SCALAR_IS_FLOAT 1
+ #pragma message GR_WARN("Scalar type not defined, defaulting to float")
+#endif
+
+#if !GR_TEXT_SCALAR_IS_FLOAT && \
+ !GR_TEXT_SCALAR_IS_FIXED && \
+ !GR_TEXT_SCALAR_IS_USHORT
+ #undef GR_TEXT_SCALAR_IS_FLOAT
+ #define GR_TEXT_SCALAR_IS_FLOAT 1
+ #pragma message GR_WARN("Text scalar type not defined, defaulting to float")
+#endif
+
+#if 0
+#if GR_WIN32_BUILD
+// #pragma message GR_WARN("GR_WIN32_BUILD")
+#endif
+#if GR_MAC_BUILD
+// #pragma message GR_WARN("GR_MAC_BUILD")
+#endif
+#if GR_IOS_BUILD
+// #pragma message GR_WARN("GR_IOS_BUILD")
+#endif
+#if GR_ANDROID_BUILD
+// #pragma message GR_WARN("GR_ANDROID_BUILD")
+#endif
+#if GR_LINUX_BUILD
+// #pragma message GR_WARN("GR_LINUX_BUILD")
+#endif
+#if GR_QNX_BUILD
+// #pragma message GR_WARN("GR_QNX_BUILD")
+#endif
+#endif
+
+#endif
+
diff --git a/gpu/include/GrContext.h b/gpu/include/GrContext.h
new file mode 100644
index 0000000000..f9d5ed5090
--- /dev/null
+++ b/gpu/include/GrContext.h
@@ -0,0 +1,322 @@
+/*
+ Copyright 2010 Google Inc.
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ */
+
+#ifndef GrContext_DEFINED
+#define GrContext_DEFINED
+
+#include "GrClip.h"
+#include "GrGpu.h"
+#include "GrSamplerState.h"
+#include "GrTextureCache.h"
+#include "GrInOrderDrawBuffer.h"
+#include "GrVertexBufferAllocPool.h"
+
+class GrFontCache;
+class GrPathIter;
+
+//TODO: move GrGpu enums/nested types here
+
+class GrContext : public GrRefCnt {
+public:
+ /**
+ * Creates a GrContext from within a 3D context.
+ */
+ static GrContext* Create(GrGpu::Engine engine,
+ GrGpu::Platform3DContext context3D);
+
+ virtual ~GrContext();
+
+ /**
+ * The GrContext normally assumes that no outsider is setting state
+ * within the underlying 3D API's context/device/whatever. This call informs
+ * the context that the state was modified and it should resend. Shouldn't
+ * be called frequently for good performance.
+ */
+ void resetContext();
+
+ /**
+ * Abandons all textures. Call this if you have lost the associated GPU
+ * context, and thus internal texture references/IDs are now invalid.
+ */
+ void abandonAllTextures();
+
+ /**
+ * Search for an entry with the same Key. If found, "lock" it and return it.
+ * If not found, return null.
+ */
+ GrTextureEntry* findAndLockTexture(GrTextureKey*,
+ const GrSamplerState&);
+
+
+ /**
+ * Create a new entry, based on the specified key and texture, and return
+ * its "locked" entry.
+ *
+ * Ownership of the texture is transferred to the Entry, which will unref()
+ * it when we are purged or deleted.
+ */
+ GrTextureEntry* createAndLockTexture(GrTextureKey* key,
+ const GrSamplerState&,
+ const GrGpu::TextureDesc&,
+ void* srcData, size_t rowBytes);
+
+ /**
+ * When done with an entry, call unlockTexture(entry) on it, which returns
+ * it to the cache, where it may be purged.
+ */
+ void unlockTexture(GrTextureEntry* entry);
+
+ /**
+ * Removes an texture from the cache. This prevents the texture from
+ * being found by a subsequent findAndLockTexture() until it is
+ * reattached. The entry still counts against the cache's budget and should
+ * be reattached when exclusive access is no longer needed.
+ */
+ void detachCachedTexture(GrTextureEntry*);
+
+ /**
+ * Reattaches a texture to the cache and unlocks it. Allows it to be found
+ * by a subsequent findAndLock or be purged (provided its lock count is
+ * now 0.)
+ */
+ void reattachAndUnlockCachedTexture(GrTextureEntry*);
+
+ /**
+ * Creates a texture that is outside the cache. Does not count against
+ * cache's budget.
+ */
+ GrTexture* createUncachedTexture(const GrGpu::TextureDesc&,
+ void* srcData,
+ size_t rowBytes);
+
+ /**
+ * Wraps an externally-created rendertarget in a GrRenderTarget.
+ * e.g. in GL platforamRenderTarget is an FBO id.
+ */
+ GrRenderTarget* createPlatformRenderTarget(intptr_t platformRenderTarget,
+ int width, int height);
+
+ /**
+ * Returns true if the specified use of an indexed texture is supported.
+ */
+ bool supportsIndex8PixelConfig(const GrSamplerState&, int width, int height);
+
+ ///////////////////////////////////////////////////////////////////////////
+
+ GrRenderTarget* currentRenderTarget() const;
+ void getViewMatrix(GrMatrix* m) const;
+ const GrClip& getClip() const { return fGpu->getClip(); }
+
+ void setRenderTarget(GrRenderTarget* target);
+ void setDefaultRenderTargetSize(uint32_t width, uint32_t height);
+ GrRenderTarget* defaultRenderTarget() { return fGpu->defaultRenderTarget(); }
+
+ void setTexture(GrTexture* texture);
+ void setSamplerState(const GrSamplerState&);
+ void setTextureMatrix(const GrMatrix& m);
+
+ void setAntiAlias(bool);
+ void setDither(bool);
+ void setAlpha(uint8_t alpha);
+ void setColor(GrColor color);
+ void setPointSize(float size);
+ void setBlendFunc(GrGpu::BlendCoeff srcCoef, GrGpu::BlendCoeff dstCoef);
+ void setViewMatrix(const GrMatrix& m);
+ void setClip(const GrClip&);
+
+ /**
+ * Erase the entire render target, ignoring any clips/scissors.
+ */
+ void eraseColor(GrColor color);
+
+ /**
+ * Draw everywhere (respecting the clip) with the current color.
+ */
+ void drawFull(bool useTexture);
+
+ /**
+ * Draw the rect, respecting the current texture if useTexture is true.
+ * If strokeWidth < 0, then the rect is filled, else the rect is stroked
+ * based on strokeWidth. If strokeWidth == 0, then the stroke is always
+ * a single pixel thick.
+ */
+ void drawRect(const GrRect&, bool useTexture, GrScalar strokeWidth);
+
+ void fillRect(const GrRect& rect, bool useTexture) {
+ this->drawRect(rect, useTexture, -1);
+ }
+
+ /**
+ * Path filling rules
+ */
+ enum PathFills {
+ kWinding_PathFill,
+ kEvenOdd_PathFill,
+ kInverseWinding_PathFill,
+ kInverseEvenOdd_PathFill,
+ kHairLine_PathFill,
+
+ kPathFillCount
+ };
+
+ /**
+ * Tessellates and draws a path.
+ *
+ * @param path the path to draw
+ * @param paint the paint to set before drawing
+ * @param useTexture if true the path vertices will also be used as
+ * texture coorindates referencing last texture passed
+ * to setTexture.
+ */
+ void drawPath(GrPathIter* path,
+ PathFills fill,
+ bool useTexture,
+ const GrPoint* translate = NULL);
+
+ /**
+ * Call to ensure all drawing to the context has been issued to the
+ * underlying 3D API.
+ * if flushRenderTarget is true then after the call the last
+ * rendertarget set will be current in the underlying 3D API, otherwise
+ * it may not be. It is useful to set if the caller plans to use the 3D
+ * context outside of Ganesh to render into the current RT.
+ */
+ void flush(bool flushRenderTarget);
+
+ /**
+ * Return true on success, i.e. if we could copy the specified range of
+ * pixels from the current render-target into the buffer, converting into
+ * the specified pixel-config.
+ */
+ bool readPixels(int left, int top, int width, int height,
+ GrTexture::PixelConfig, void* buffer);
+
+ /**
+ * Copy the src pixels [buffer, stride, pixelconfig] into the current
+ * render-target at the specified rectangle.
+ */
+ void writePixels(int left, int top, int width, int height,
+ GrTexture::PixelConfig, const void* buffer, size_t stride);
+
+ /* -------------------------------------------------------
+ * Mimicking the GrGpu interface for now
+ * TODO: define appropriate higher-level API for context
+ */
+
+ GrVertexBuffer* createVertexBuffer(uint32_t size, bool dynamic);
+
+ GrIndexBuffer* createIndexBuffer(uint32_t size, bool dynamic);
+
+ bool reserveAndLockGeometry(GrVertexLayout vertexLayout,
+ uint32_t vertexCount,
+ uint32_t indexCount,
+ void** vertices,
+ void** indices);
+
+ void drawIndexed(GrGpu::PrimitiveType type,
+ uint32_t startVertex,
+ uint32_t startIndex,
+ uint32_t vertexCount,
+ uint32_t indexCount);
+
+ void drawNonIndexed(GrGpu::PrimitiveType type,
+ uint32_t startVertex,
+ uint32_t vertexCount);
+
+ void setVertexSourceToArray(const void* array,
+ GrVertexLayout vertexLayout);
+ void setIndexSourceToArray(const void* array);
+ void setVertexSourceToBuffer(GrVertexBuffer* buffer,
+ GrVertexLayout vertexLayout);
+ void setIndexSourceToBuffer(GrIndexBuffer* buffer);
+
+ void releaseReservedGeometry();
+
+ void resetStats();
+
+ const GrGpu::Stats& getStats() const;
+
+ void printStats() const;
+
+ class AutoRenderTarget : ::GrNoncopyable {
+ public:
+ AutoRenderTarget(GrContext* context, GrRenderTarget* target) {
+ fContext = NULL;
+ fPrevTarget = context->currentRenderTarget();
+ if (fPrevTarget != target) {
+ context->setRenderTarget(target);
+ fContext = context;
+ }
+ }
+ ~AutoRenderTarget() {
+ if (fContext) {
+ fContext->setRenderTarget(fPrevTarget);
+ }
+ }
+ private:
+ GrContext* fContext;
+ GrRenderTarget* fPrevTarget;
+ };
+
+ /* -------------------------------------------------------
+ */
+
+ // Intended only to be used within Ganesh:
+ GrGpu* getGpu() { return fGpu; }
+ GrFontCache* getFontCache() { return fFontCache; }
+ GrDrawTarget* getTextTarget();
+ void flushText();
+
+ const GrIndexBuffer* quadIndexBuffer() const;
+ int maxQuadsInIndexBuffer() const;
+
+private:
+ GrGpu* fGpu;
+ GrTextureCache* fTextureCache;
+ GrFontCache* fFontCache;
+
+ GrVertexBufferAllocPool fVBAllocPool;
+ GrInOrderDrawBuffer fTextDrawBuffer;
+
+ GrContext(GrGpu* gpu);
+ bool finalizeTextureKey(GrTextureKey*, const GrSamplerState&) const;
+
+ void drawClipIntoStencil();
+};
+
+/**
+ * Save/restore the view-matrix in the context.
+ */
+class GrAutoViewMatrix : GrNoncopyable {
+public:
+ GrAutoViewMatrix(GrContext* ctx) : fContext(ctx) {
+ ctx->getViewMatrix(&fMatrix);
+ }
+ GrAutoViewMatrix(GrContext* ctx, const GrMatrix& matrix) : fContext(ctx) {
+ ctx->getViewMatrix(&fMatrix);
+ ctx->setViewMatrix(matrix);
+ }
+ ~GrAutoViewMatrix() {
+ fContext->setViewMatrix(fMatrix);
+ }
+
+private:
+ GrContext* fContext;
+ GrMatrix fMatrix;
+};
+
+#endif
+
diff --git a/gpu/include/GrDrawTarget.h b/gpu/include/GrDrawTarget.h
new file mode 100644
index 0000000000..fee13a6c7e
--- /dev/null
+++ b/gpu/include/GrDrawTarget.h
@@ -0,0 +1,736 @@
+/*
+ Copyright 2010 Google Inc.
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ */
+
+
+#ifndef GrDrawTarget_DEFINED
+#define GrDrawTarget_DEFINED
+
+#include "GrScalar.h"
+#include "GrMatrix.h"
+#include "GrColor.h"
+#include "GrRefCnt.h"
+#include "GrSamplerState.h"
+#include "GrClip.h"
+
+class GrTexture;
+class GrRenderTarget;
+class GrClipIterator;
+class GrVertexBuffer;
+class GrIndexBuffer;
+
+class GrDrawTarget : public GrRefCnt {
+public:
+ /**
+ * Geometric primitives used for drawing.
+ */
+ enum PrimitiveType {
+ kTriangles_PrimitiveType,
+ kTriangleStrip_PrimitiveType,
+ kTriangleFan_PrimitiveType,
+ kPoints_PrimitiveType,
+ kLines_PrimitiveType,
+ kLineStrip_PrimitiveType
+ };
+
+ /**
+ * Flags that affect rendering. Controlled using enable/disableState(). All
+ * default to disabled.
+ */
+ enum StateBits {
+ kDither_StateBit = 0x1,//<! Perform color dithering
+ kAntialias_StateBit = 0x2,//<! Perform anti-aliasing. The render-
+ // target must support some form of AA
+ // (msaa, coverage sampling, etc). For
+ // GrGpu-created rendertarget/textures
+ // this is controlled by parameters
+ // passed to createTexture.
+ kClip_StateBit = 0x4,//<! Controls whether drawing is clipped
+ // against the region specified by
+ // setClip.
+ };
+
+ /**
+ * Coeffecients for alpha-blending.
+ */
+ enum BlendCoeff {
+ kZero_BlendCoeff, //<! 0
+ kOne_BlendCoeff, //<! 1
+ kSC_BlendCoeff, //<! src color
+ kISC_BlendCoeff, //<! one minus src color
+ kDC_BlendCoeff, //<! dst color
+ kIDC_BlendCoeff, //<! one minus dst color
+ kSA_BlendCoeff, //<! src alpha
+ kISA_BlendCoeff, //<! one minus src alpha
+ kDA_BlendCoeff, //<! dst alpha
+ kIDA_BlendCoeff, //<! one minus dst alpha
+ };
+
+ /**
+ * StencilPass
+ *
+ * Sets the stencil state for subsequent draw calls. Used to fill paths.
+ *
+ * Winding requires two passes when the GPU/API doesn't support separate
+ * stencil.
+ *
+ * The color pass for path fill is used to zero out stencil bits used for
+ * path filling. Every pixel covere by a winding/EO stencil pass must get
+ * covered by the color pass in order to leave stencil buffer in the correct
+ * state for the next path draw.
+ *
+ * NOTE: Stencil-based Winding fill has alias-to-zero problems. (e.g. A
+ * winding count of 128,256,512,etc with a 8 bit stencil buffer
+ * will be unfilled)
+ */
+ enum StencilPass {
+ kNone_StencilPass, //<! Not drawing a path or clip.
+ kEvenOddStencil_StencilPass, //<! records in/out in stencil buffer
+ // using the Even/Odd fill rule.
+ kEvenOddColor_StencilPass, //<! writes colors to color target in
+ // pixels marked inside the fill by
+ // kEOFillStencil_StencilPass. Clears
+ // stencil in pixels covered by
+ // geometry.
+ kWindingStencil1_StencilPass, //<! records in/out in stencil buffer
+ // using the Winding fill rule.
+ kWindingStencil2_StencilPass, //<! records in/out in stencil buffer
+ // using the Winding fill rule.
+ // Run when single-stencil-pass winding
+ // not supported (i.e. no separate
+ // stencil support)
+ kWindingColor_StencilPass, //<! writes colors to color target in
+ // pixels marked inside the fill by
+ // kWindFillStencil_StencilPass. Clears
+ // stencil in pixels covered by
+ // geometry.
+ kDrawTargetCount_StencilPass //<! Subclass may extend this enum to use
+ // the stencil for other purposes (e.g.
+ // to do stencil-based clipping)
+ // This value is provided as basis for
+ // defining these extended enum values.
+ };
+
+protected:
+ enum MatrixMode {
+ kModelView_MatrixMode = 0,
+ kTexture_MatrixMode,
+
+ kMatrixModeCount
+ };
+
+ struct DrawState {
+ uint32_t fFlagBits;
+ BlendCoeff fSrcBlend;
+ BlendCoeff fDstBlend;
+ GrTexture* fTexture;
+ GrSamplerState fSamplerState;
+ GrRenderTarget* fRenderTarget;
+ GrColor fColor;
+ float fPointSize;
+ StencilPass fStencilPass;
+ bool fReverseFill;
+ GrMatrix fMatrixModeCache[kMatrixModeCount];
+ bool operator ==(const DrawState& s) const {
+ return 0 == memcmp(this, &s, sizeof(DrawState));
+ }
+ bool operator !=(const DrawState& s) const { return !(*this == s); }
+ };
+
+public:
+ ///////////////////////////////////////////////////////////////////////////
+
+ GrDrawTarget();
+
+ /**
+ * Sets the current clip to the region specified by clip. All draws will be
+ * clipped against this clip if kClip_StateBit is enabled.
+ *
+ * @param description of the clipping region
+ */
+ void setClip(const GrClip& clip);
+
+ /**
+ * Gets the current clip.
+ *
+ * @return the clip.
+ */
+ const GrClip& getClip() const;
+
+ /**
+ * Sets the texture used at the next drawing call
+ *
+ * @param texture The texture to set. Can be NULL though there is no advantage
+ * to settings a NULL texture if doing non-textured drawing
+ */
+ void setTexture(GrTexture* texture);
+
+ /**
+ * Retrieves the currently set texture.
+ *
+ * @return The currently set texture. The return value will be NULL if no
+ * texture has been set, NULL was most recently passed to
+ * setTexture, or the last setTexture was destroyed.
+ */
+ GrTexture* currentTexture() const;
+
+ /**
+ * Sets the rendertarget used at the next drawing call
+ *
+ * @param target The render target to set. Must be a valid rendertarget.
+ * That is it is a value that was returned by
+ * currentRenderTarget() or GrTexture::asRenderTarget().
+ */
+ void setRenderTarget(GrRenderTarget* target);
+
+ /**
+ * Retrieves the currently set rendertarget.
+ *
+ * @return The currently set render target.
+ */
+ GrRenderTarget* currentRenderTarget() const;
+
+ /**
+ * Sets the sampler state for the next draw.
+ *
+ * The sampler state determines the address wrap modes and
+ * filtering
+ *
+ * @param samplerState Specifies the sampler state.
+ */
+ void setSamplerState(const GrSamplerState& samplerState);
+
+ /**
+ * Sets the matrix applied to texture coordinates.
+ *
+ * The post-matrix texture coordinates in the square [0,1]^2 cover the
+ * entire area of the texture. This means the full POT width when a NPOT
+ * texture is embedded in a POT width texture to meet the 3D API
+ * requirements. The texture matrix is applied both when the texture
+ * coordinates are explicit and when vertex positions are used as texture
+ * coordinates. In the latter case the texture matrix is applied to the
+ * pre-modelview position values.
+ *
+ * @param m the matrix used to transform the texture coordinates.
+ */
+ void setTextureMatrix(const GrMatrix& m) {
+ this->loadMatrix(m, kTexture_MatrixMode);
+ }
+
+ /**
+ * Sets the matrix applied to veretx positions.
+ *
+ * In the post-view-matrix space the rectangle [0,w]x[0,h]
+ * fully covers the render target. (w and h are the width and height of the
+ * the rendertarget.)
+ *
+ * @param m the matrix used to transform the vertex positions.
+ */
+ void setViewMatrix(const GrMatrix& m) {
+ this->loadMatrix(m, kModelView_MatrixMode);
+ }
+
+ /**
+ * Multiplies the current view matrix by a matrix
+ *
+ * After this call V' = V*m where V is the old view matrix,
+ * m is the parameter to this function, and V' is the new view matrix.
+ * (We consider positions to be column vectors so position vector p is
+ * transformed by matrix X as p' = X*p.)
+ *
+ * @param m the matrix used to modify the modelview matrix.
+ */
+ void concatViewMatrix(const GrMatrix& m);
+
+ /**
+ * Sets color for next draw to a premultiplied-alpha color.
+ *
+ * @param the color to set.
+ */
+ void setColor(GrColor);
+
+ /**
+ * Sets the color to be used for the next draw to be
+ * (r,g,b,a) = (alpha, alpha, alpha, alpha).
+ *
+ * @param alpha The alpha value to set as the color.
+ */
+ void setAlpha(uint8_t alpha);
+
+ /**
+ * Sets pass for path rendering
+ *
+ * @param pass of path rendering
+ */
+ void setStencilPass(StencilPass pass);
+
+ /**
+ * Reveses the in/out decision of the fill rule for path rendering.
+ * Only affects kEOFillColor_StencilPass and kWindingFillColor_StencilPass
+ *
+ * @param reverse true to reverse, false otherwise
+ */
+ void setReverseFill(bool reverse);
+
+ /**
+ * Enable render state settings.
+ *
+ * @param flags bitfield of StateBits specifing the states to enable
+ */
+ void enableState(uint32_t stateBits);
+
+ /**
+ * Disable render state settings.
+ *
+ * @param flags bitfield of StateBits specifing the states to disable
+ */
+ void disableState(uint32_t stateBits);
+
+ bool isDitherState() const {
+ return fCurrDrawState.fFlagBits & kDither_StateBit;
+ }
+
+ /**
+ * Sets the size of points used the next time points are drawn.
+ *
+ * @param the point size
+ */
+ void setPointSize(float size);
+
+ /**
+ * Sets the blending function coeffecients.
+ *
+ * The blend function will be:
+ * D' = sat(S*srcCoef + D*dstCoef)
+ *
+ * where D is the existing destination color, S is the incoming source
+ * color, and D' is the new destination color that will be written. sat()
+ * is the saturation function.
+ *
+ * @param srcCoef coeffecient applied to the src color.
+ * @param dstCoef coeffecient applied to the dst color.
+ */
+ void setBlendFunc(BlendCoeff srcCoef, BlendCoeff dstCoef);
+
+ /**
+ * Retrieves the current view matrix
+ * @param matrix will be the current view matrix after return.
+ */
+ void getViewMatrix(GrMatrix* matrix) const;
+
+ /**
+ * Retrieves the inverse of the current view matrix.
+ *
+ * If the current view matrix is invertible, return true, and if matrix
+ * is non-null, copy the inverse into it. If the current view matrix is
+ * non-invertible, return false and ignore the matrix parameter.
+ *
+ * @param matrix if not null, will receive a copy of the current inverse.
+ */
+ bool getViewInverse(GrMatrix* matrix) const;
+
+ /**
+ * Used to save and restore the GrGpu's drawing state
+ */
+ struct SavedDrawState {
+ private:
+ DrawState fState;
+ friend class GrDrawTarget;
+ };
+
+ /**
+ * Saves the current draw state. The state can be restored at a later time
+ * with restoreDrawState.
+ *
+ * See also AutoStateRestore class.
+ *
+ * @param state will hold the state after the function returns.
+ */
+ void saveCurrentDrawState(SavedDrawState* state) const;
+
+ /**
+ * Restores previously saved draw state. The client guarantees that state
+ * was previously passed to saveCurrentDrawState and that the rendertarget
+ * and texture set at save are still valid.
+ *
+ * See also AutoStateRestore class.
+ *
+ * @param state the previously saved state to restore.
+ */
+ void restoreDrawState(const SavedDrawState& state);
+
+ /**
+ * Copies the draw state from another target to this target.
+ *
+ * @param srcTarget draw target used as src of the draw state.
+ */
+ void copyDrawState(const GrDrawTarget& srcTarget);
+
+ /**
+ * Flags that indicate the layout of vertex data.
+ *
+ * kSeparateTexCoord_VertexLayoutBit is incompatible with
+ * kPositionAsTexCoord_VertexLayoutBit. kTextFormat_VertexLayoutBit is
+ * incompatible with any other flags.
+ *
+ * When kTextFormat_VertexLayoutBit is set:
+ * Texture coordinates are separate.
+ * Positions and Texture coordinates are SkGpuTextVertex.
+ * For non-text vertices:
+ * Position and texture coordinates are GrPoints.
+ * Colors are GrColors.
+ *
+ * The order is always positions, texture coords, colors.
+ */
+ enum VertexLayoutBits {
+ kSeparateTexCoord_VertexLayoutBit = 0x1, //<! vertices have texture
+ // coords that are not
+ // inferred from the
+ // positions
+ kPositionAsTexCoord_VertexLayoutBit = 0x2, //<! vertices use positions
+ // as texture coords.
+ kColor_VertexLayoutBit = 0x4, //<! vertices have colors
+ kTextFormat_VertexLayoutBit = 0x8, //<! vertices represent glyphs
+ // and therefore contain
+ // two GrGpuTextVertexs.
+ // One for pos and one for
+ // text coords.
+ // for below assert
+ kDummy,
+ kHighVertexLayoutBit = kDummy - 1
+ };
+ GR_STATIC_ASSERT(kHighVertexLayoutBit < (1 << 8*sizeof(GrVertexLayout)));
+
+ /**
+ * Reserves space for vertices and/or indices. Draw target will use
+ * reserved vertices / indices at next draw.
+ *
+ * If succeeds:
+ * if vertexCount is nonzero, *vertices will be the array
+ * of vertices to be filled by caller. The next draw will read
+ * these vertices.
+ *
+ * if indecCount is nonzero, *indices will be the array of indices
+ * to be filled by caller. The next indexed draw will read from
+ * these indices.
+ *
+ * If a client does not already have a vertex buffer or cpu arrays then this
+ * is the preferred way to allocate vertex/index array. It allows the
+ * subclass of GrDrawTarget to decide whether to put data in buffers, to
+ * group vertex data that uses the same state (e.g. for deferred rendering),
+ * etc.
+ *
+ * This must be matched with a releaseReservedGeometry call after all
+ * draws that reference the reserved geometry data have been called.
+ *
+ * AutoGeometryRelease can be used to automatically call the release.
+ *
+ * @param vertexCount the number of vertices to reserve space for. Can be 0.
+ * @param indexCount the number of indices to reserve space for. Can be 0.
+ * @param vertexLayout the format of vertices (ignored if vertexCount == 0).
+ * @param vertices will point to reserved vertex space if vertexCount is
+ * non-zero. Illegal to pass NULL if vertexCount > 0.
+ * @param indices will point to reserved index space if indexCount is
+ * non-zero. Illegal to pass NULL if indexCount > 0.
+ *
+ * @return true if succeeded in allocating space for the vertices and false
+ * if not.
+ */
+ bool reserveAndLockGeometry(GrVertexLayout vertexLayout,
+ uint32_t vertexCount,
+ uint32_t indexCount,
+ void** vertices,
+ void** indices);
+ /**
+ * Provides hints to caller about the number of vertices and indices
+ * that can be allocated cheaply. This can be useful if caller is reserving
+ * space but doesn't know exactly how much geometry is needed.
+ *
+ * Also may hint whether the draw target should be flushed first. This is
+ * useful for deferred targets.
+ *
+ * @param vertexLayout layout of vertices caller would like to reserve
+ * @param vertexCount in: hint about how many vertices the caller would
+ * like to allocate.
+ * out: a hint about the number of vertices that can be
+ * allocated cheaply. Negative means no hint.
+ * Ignored if NULL.
+ * @param indexCount in: hint about how many indices the caller would
+ * like to allocate.
+ * out: a hint about the number of indices that can be
+ * allocated cheaply. Negative means no hint.
+ * Ignored if NULL.
+ *
+ * @return true if target should be flushed based on the input values.
+ */
+ virtual bool geometryHints(GrVertexLayout vertexLayout,
+ int32_t* vertexCount,
+ int32_t* indexCount) const;
+
+ /**
+ * Releases reserved vertex/index data from reserveAndLockGeometry().
+ */
+ void releaseReservedGeometry();
+
+ /**
+ * Sets source of vertex data for the next draw. Data does not have to be
+ * in the array until drawIndexed or drawNonIndexed.
+ *
+ * @param array cpu array containing vertex data.
+ * @param vertexLayout layout of the vertex data in the array.
+ */
+ void setVertexSourceToArray(const void* array, GrVertexLayout vertexLayout);
+
+ /**
+ * Sets source of index data for the next indexed draw. Data does not have
+ * to be in the array until drawIndexed or drawNonIndexed.
+ *
+ * @param array cpu array containing index data.
+ */
+ void setIndexSourceToArray(const void* array);
+
+ /**
+ * Sets source of vertex data for the next draw. Data does not have to be
+ * in the buffer until drawIndexed or drawNonIndexed.
+ *
+ * @param buffer vertex buffer containing vertex data. Must be
+ * unlocked before draw call.
+ * @param vertexLayout layout of the vertex data in the buffer.
+ */
+ void setVertexSourceToBuffer(const GrVertexBuffer* buffer,
+ GrVertexLayout vertexLayout);
+
+ /**
+ * Sets source of index data for the next indexed draw. Data does not have
+ * to be in the buffer until drawIndexed or drawNonIndexed.
+ *
+ * @param buffer index buffer containing indices. Must be unlocked
+ * before indexed draw call.
+ */
+ void setIndexSourceToBuffer(const GrIndexBuffer* buffer);
+
+ /**
+ * Draws indexed geometry using the current state and current vertex / index
+ * sources.
+ *
+ * @param type The type of primitives to draw.
+ * @param startVertex the vertex in the vertex array/buffer corresponding
+ * to index 0
+ * @param startIndex first index to read from index src.
+ * @param vertexCount one greater than the max index.
+ * @param indexCount the number of index elements to read. The index count
+ * is effectively trimmed to the last completely
+ * specified primitive.
+ */
+ virtual void drawIndexed(PrimitiveType type,
+ uint32_t startVertex,
+ uint32_t startIndex,
+ uint32_t vertexCount,
+ uint32_t indexCount) = 0;
+
+ /**
+ * Draws non-indexed geometry using the current state and current vertex
+ * sources.
+ *
+ * @param type The type of primitives to draw.
+ * @param startVertex the vertex in the vertex array/buffer corresponding
+ * to index 0
+ * @param vertexCount one greater than the max index.
+ */
+ virtual void drawNonIndexed(PrimitiveType type,
+ uint32_t startVertex,
+ uint32_t vertexCount) = 0;
+
+ ///////////////////////////////////////////////////////////////////////////
+
+ class AutoStateRestore : ::GrNoncopyable {
+ public:
+ AutoStateRestore(GrDrawTarget* target);
+ ~AutoStateRestore();
+
+ private:
+ GrDrawTarget* fDrawTarget;
+ SavedDrawState fDrawState;
+ };
+
+ ///////////////////////////////////////////////////////////////////////////
+
+ class AutoReleaseGeometry : ::GrNoncopyable {
+ public:
+ AutoReleaseGeometry(GrDrawTarget* target,
+ GrVertexLayout vertexLayout,
+ uint32_t vertexCount,
+ uint32_t indexCount) {
+ fTarget = target;
+ fSuccess = fTarget->reserveAndLockGeometry(vertexLayout,
+ vertexCount,
+ indexCount,
+ &fVertices,
+ &fIndices);
+ }
+ ~AutoReleaseGeometry() {
+ if (fSuccess) {
+ fTarget->releaseReservedGeometry();
+ }
+ }
+
+ bool succeeded() const { return fSuccess; }
+ void* vertices() const { return fVertices; }
+ void* indices() const { return fIndices; }
+
+ GrPoint* positions() const {
+ return static_cast<GrPoint*>(fVertices);
+ }
+
+ private:
+ GrDrawTarget* fTarget;
+ bool fSuccess;
+ void* fVertices;
+ void* fIndices;
+ };
+
+ ///////////////////////////////////////////////////////////////////////////
+
+ class AutoClipRestore : ::GrNoncopyable {
+ public:
+ AutoClipRestore(GrDrawTarget* target) {
+ fTarget = target;
+ fClip = fTarget->getClip();
+ }
+
+ ~AutoClipRestore() {
+ fTarget->setClip(fClip);
+ }
+ private:
+ GrDrawTarget* fTarget;
+ GrClip fClip;
+ };
+
+ ////////////////////////////////////////////////////////////////////////////
+
+ /**
+ * Helper function to compute the size of a vertex from a vertex layout
+ * @return size of a single vertex.
+ */
+ static size_t VertexSize(GrVertexLayout vertexLayout);
+
+ /**
+ * Helper function to compute the offset of texture coordinates in a vertex
+ * @return offset of texture coordinates in vertex layout or -1 if the
+ * layout has no texture coordinates.
+ */
+ static int VertexTexCoordOffset(GrVertexLayout vertexLayout);
+
+ /**
+ * Helper function to compute the offset of the color in a vertex
+ * @return offset of color in vertex layout or -1 if the
+ * layout has no color.
+ */
+ static int VertexColorOffset(GrVertexLayout vertexLayout);
+
+ /**
+ * Helper function to compute vertex size and component offsets.
+ * @param texCoordOffset after return it is the offset of texture coords
+ * in vertex layout or -1 if the layout has no
+ * texture coords.
+ * @param colorOffset after return it is the offset of color in vertex
+ * layout or -1 if the layout has no color.
+ * @return size of a single vertex.
+ */
+ static int VertexSizeAndOffsets(GrVertexLayout vertexLayout,
+ int* texCoordOffset,
+ int* colorOffset);
+ /**
+ * Helper function to determine if vertex layout contains either explicit or
+ * implicit texture coordinates.
+ *
+ * @return true if vertex specifies texture coordinates, false otherwise.
+ */
+ static bool VertexHasTexCoords(GrVertexLayout vertexLayout);
+
+protected:
+
+ // Helpers for GrDrawTarget subclasses that won't have private access to
+ // SavedDrawState but need to peek at the state values.
+ static DrawState& accessSavedDrawState(SavedDrawState& sds)
+ { return sds.fState; }
+ static const DrawState& accessSavedDrawState(const SavedDrawState& sds)
+ { return sds.fState; }
+
+ // implemented by subclass
+ virtual bool acquireGeometryHelper(GrVertexLayout vertexLayout,
+ void** vertices,
+ void** indices) = 0;
+
+ virtual void releaseGeometryHelper() = 0;
+
+ virtual void clipWillChange(const GrClip& clip) = 0;
+
+ enum GeometrySrcType {
+ kArray_GeometrySrcType,
+ kReserved_GeometrySrcType,
+ kBuffer_GeometrySrcType
+ };
+
+ struct {
+ bool fLocked;
+ uint32_t fVertexCount;
+ uint32_t fIndexCount;
+ } fReservedGeometry;
+
+ struct GeometrySrc {
+ GeometrySrcType fVertexSrc;
+ union {
+ const GrVertexBuffer* fVertexBuffer;
+ const void* fVertexArray;
+ };
+ GeometrySrcType fIndexSrc;
+ union {
+ const GrIndexBuffer* fIndexBuffer;
+ const void* fIndexArray;
+ };
+ GrVertexLayout fVertexLayout;
+ } fGeometrySrc;
+
+ GrClip fClip;
+
+ DrawState fCurrDrawState;
+
+ // set texture or modelview matrix
+ void loadMatrix(const GrMatrix&, MatrixMode);
+
+ // not meant for outside usage. Could cause problems if calls between
+ // the save and restore mess with reserved geometry state.
+ class AutoGeometrySrcRestore {
+ public:
+ AutoGeometrySrcRestore(GrDrawTarget* target) {
+ fTarget = target;
+ fGeometrySrc = fTarget->fGeometrySrc;
+ }
+ ~AutoGeometrySrcRestore() {
+ fTarget->fGeometrySrc = fGeometrySrc;
+ }
+ private:
+ GrDrawTarget *fTarget;
+ GeometrySrc fGeometrySrc;
+
+ AutoGeometrySrcRestore();
+ AutoGeometrySrcRestore(const AutoGeometrySrcRestore&);
+ AutoGeometrySrcRestore& operator =(AutoGeometrySrcRestore&);
+ };
+
+};
+
+#endif
diff --git a/gpu/include/GrFontScaler.h b/gpu/include/GrFontScaler.h
new file mode 100644
index 0000000000..6baa56fff3
--- /dev/null
+++ b/gpu/include/GrFontScaler.h
@@ -0,0 +1,43 @@
+/*
+ Copyright 2010 Google Inc.
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ */
+
+
+#ifndef GrFontScaler_DEFINED
+#define GrFontScaler_DEFINED
+
+#include "GrGlyph.h"
+#include "GrKey.h"
+
+class GrPath;
+
+/**
+ * This is a virtual base class which Gr's interface to the host platform's
+ * font scaler.
+ *
+ * The client is responsible for subclassing, and instantiating this. The
+ * instance is create for a specific font+size+matrix.
+ */
+class GrFontScaler : public GrRefCnt {
+public:
+ virtual const GrKey* getKey() = 0;
+ virtual bool getPackedGlyphBounds(GrGlyph::PackedID, GrIRect* bounds) = 0;
+ virtual bool getPackedGlyphImage(GrGlyph::PackedID, int width, int height,
+ int rowBytes, void* image) = 0;
+ virtual bool getGlyphPath(uint16_t glyphID, GrPath*) = 0;
+};
+
+#endif
+
diff --git a/gpu/include/GrGLConfig.h b/gpu/include/GrGLConfig.h
new file mode 100644
index 0000000000..90763abc5c
--- /dev/null
+++ b/gpu/include/GrGLConfig.h
@@ -0,0 +1,323 @@
+/*
+ Copyright 2010 Google Inc.
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ */
+
+
+#ifndef GrGLConfig_DEFINED
+#define GrGLConfig_DEFINED
+
+#include "GrTypes.h"
+
+#if GR_WIN32_BUILD
+ // glew has to be included before gl
+ #define GR_INCLUDE_GLDESKTOP <GL/glew.h>
+ #define GR_INCLUDE_GLDESKTOPext <GL/gl.h>
+ #define GR_GL_FUNC __stdcall
+ // undo stupid windows defines
+ #undef near
+ #undef far
+#elif GR_MAC_BUILD
+ #define GR_INCLUDE_GLDESKTOP <OpenGL/gl.h>
+ #define GR_INCLUDE_GLDESKTOPext <OpenGL/glext.h>
+ #define GR_GL_FUNC
+#elif GR_IOS_BUILD
+ #define GR_INCLUDE_GLES1 <OpenGLES/ES1/gl.h>
+ #define GR_INCLUDE_GLES1ext <OpenGLES/ES1/glext.h>
+ #define GR_INCLUDE_GLES2 <OpenGLES/ES2/gl.h>
+ #define GR_INCLUDE_GLES2ext <OpenGLES/ES2/glext.h>
+ #define GR_GL_FUNC
+#elif GR_ANDROID_BUILD
+ #ifndef GL_GLEXT_PROTOTYPES
+ #define GL_GLEXT_PROTOTYPES
+ #endif
+ #define GR_INCLUDE_GLES2 <GLES2/gl2.h>
+ #define GR_INCLUDE_GLES2ext <GLES2/gl2ext.h>
+ #define GR_GL_FUNC
+#elif GR_LINUX_BUILD
+ // need to distinguish between ES and Deskop versions for linux
+ #ifndef GL_GLEXT_PROTOTYPES
+ #define GL_GLEXT_PROTOTYPES
+ #endif
+ #define GR_INCLUDE_GLES1 <GLES/gl.h>
+ #define GR_INCLUDE_GLES1ext <GLES/glext.h>
+ #define GR_INCLUDE_GLES2 <GLES2/gl2.h>
+ #define GR_INCLUDE_GLES2ext <GLES2/gl2ext.h>
+ #define GR_GL_FUNC
+#elif GR_QNX_BUILD
+ #ifndef GL_GLEXT_PROTOTYPES
+ #define GL_GLEXT_PROTOTYPES
+ #endif
+ // This is needed by the QNX GLES2 headers
+ #define GL_API_EXT
+ #define GR_INCLUDE_GLES2 <GLES2/gl2.h>
+ #define GR_INCLUDE_GLES2ext <GLES2/gl2ext.h>
+ #define GR_INCLUDE_EGL <EGL/egl.h>
+ #define GR_GL_FUNC
+#else
+ #error "unsupported GR_???_BUILD"
+#endif
+
+// Ensure we're at least defined
+//
+
+#ifndef GR_SUPPORT_GLES1
+ #if defined(GR_INCLUDE_GLES1)
+ #define GR_SUPPORT_GLES1 1
+ #else
+ #define GR_SUPPORT_GLES1 0
+ #endif
+#endif
+
+#ifndef GR_SUPPORT_GLES2
+ #if defined(GR_INCLUDE_GLES2)
+ #define GR_SUPPORT_GLES2 1
+ #else
+ #define GR_SUPPORT_GLES2 0
+ #endif
+#endif
+
+#ifndef GR_SUPPORT_GLDESKTOP
+ #if defined(GR_INCLUDE_GLDESKTOP)
+ #define GR_SUPPORT_GLDESKTOP 1
+ #else
+ #define GR_SUPPORT_GLDESKTOP 0
+ #endif
+#endif
+
+#ifndef GR_SUPPORT_EGL
+ #if defined(GR_INCLUDE_EGL)
+ #define GR_SUPPORT_EGL 1
+ #else
+ #define GR_SUPPORT_EGL 0
+ #endif
+#endif
+// Filter the includes based on what we support
+//
+
+#if !GR_SUPPORT_GLES1
+ #undef GR_INCLUDE_GLES1
+ #undef GR_INCLUDE_GLES1ext
+#endif
+
+#if !GR_SUPPORT_GLES2
+ #undef GR_INCLUDE_GLES2
+ #undef GR_INCLUDE_GLES2ext
+#endif
+
+#if !GR_SUPPORT_GLDESKTOP
+ #undef GR_INCLUDE_GLDESKTOP
+ #undef GR_INCLUDE_GLDESKTOPext
+#endif
+
+#if !GR_SUPPORT_EGL
+ #undef GR_INCLUDE_EGL
+#endif
+
+// Begin including GL headers
+//
+
+#ifdef GR_INCLUDE_GLES1
+ #include GR_INCLUDE_GLES1
+#endif
+#ifdef GR_INCLUDE_GLES1ext
+ #include GR_INCLUDE_GLES1ext
+#endif
+#ifdef GR_INCLUDE_GLES2
+ #include GR_INCLUDE_GLES2
+#endif
+#ifdef GR_INCLUDE_GLES2ext
+ #include GR_INCLUDE_GLES2ext
+#endif
+#ifdef GR_INCLUDE_GLDESKTOP
+ #include GR_INCLUDE_GLDESKTOP
+#endif
+#ifdef GR_INCLUDE_GLDESKTOPext
+ #include GR_INCLUDE_GLDESKTOPext
+#endif
+#ifdef GR_INCLUDE_EGL
+ #include GR_INCLUDE_EGL
+#endif
+
+//
+// End including GL headers
+
+#if GL_VERSION_1_1
+ #define GR_GL_DESKTOP 1
+ #define GR_GL_ES 0
+#else
+ #ifndef GL_ES_VERSION_2_0
+ GR_STATIC_ASSERT(GL_VERSION_ES_CM_1_0 ||
+ GL_VERSION_ES_CL_1_0 ||
+ GL_VERSION_ES_CM_1_1 ||
+ GL_VERSION_ES_CL_1_1);
+ #endif
+ #define GR_GL_DESKTOP 0
+ #define GR_GL_ES 1
+#endif
+
+#if GR_SCALAR_IS_FIXED
+ #define GrGLType GL_FIXED
+#elif GR_SCALAR_IS_FLOAT
+ #define GrGLType GL_FLOAT
+#else
+ #error "unknown GR_SCALAR type"
+#endif
+
+#if GR_TEXT_SCALAR_IS_USHORT
+ #define GrGLTextType GL_UNSIGNED_SHORT
+ #define GR_GL_TEXT_TEXTURE_NORMALIZED 1
+#elif GR_TEXT_SCALAR_IS_FLOAT
+ #define GrGLTextType GL_FLOAT
+ #define GR_GL_TEXT_TEXTURE_NORMALIZED 0
+#elif GR_TEXT_SCALAR_IS_FIXED
+ #define GrGLTextType GL_FIXED
+ #define GR_GL_TEXT_TEXTURE_NORMALIZED 0
+#else
+ #error "unknown GR_TEXT_SCALAR type"
+#endif
+
+// Pick a pixel config for 32bit bitmaps. Our default is GL_RGBA
+#ifndef SK_GL_32BPP_COLOR_FORMAT
+ #define SK_GL_32BPP_COLOR_FORMAT GL_RGBA
+#endif
+
+////////////////////////////////////////////////////////////////////////////////
+// setup for opengl ES/desktop extensions
+// we make a struct of function pointers so that each GL context
+// can have it's own struct. (Some environments may have different proc
+// addresses for different contexts).
+
+extern "C" {
+struct GrGLExts {
+// FBO
+ GLvoid (GR_GL_FUNC *GenFramebuffers)(GLsizei n, GLuint *framebuffers);
+ GLvoid (GR_GL_FUNC *BindFramebuffer)(GLenum target, GLuint framebuffer);
+ GLvoid (GR_GL_FUNC *FramebufferTexture2D)(GLenum target, GLenum attachment,
+ GLenum textarget, GLuint texture,
+ GLint level);
+ GLenum (GR_GL_FUNC *CheckFramebufferStatus)(GLenum target);
+ GLvoid (GR_GL_FUNC *DeleteFramebuffers)(GLsizei n, const
+ GLuint *framebuffers);
+ GLvoid (GR_GL_FUNC *RenderbufferStorage)(GLenum target,
+ GLenum internalformat,
+ GLsizei width, GLsizei height);
+ GLvoid (GR_GL_FUNC *GenRenderbuffers)(GLsizei n, GLuint *renderbuffers);
+ GLvoid (GR_GL_FUNC *DeleteRenderbuffers)(GLsizei n,
+ const GLuint *renderbuffers);
+ GLvoid (GR_GL_FUNC *FramebufferRenderbuffer)(GLenum target,
+ GLenum attachment,
+ GLenum renderbuffertarget,
+ GLuint renderbuffer);
+ GLvoid (GR_GL_FUNC *BindRenderbuffer)(GLenum target, GLuint renderbuffer);
+
+// Multisampling
+ // same prototype for ARB_FBO, EXT_FBO, GL 3.0, & Apple ES extension
+ GLvoid (GR_GL_FUNC *RenderbufferStorageMultisample)(GLenum target,
+ GLsizei samples,
+ GLenum internalformat,
+ GLsizei width,
+ GLsizei height);
+ // desktop: ext_fbo_blit, arb_fbo, gl 3.0
+ GLvoid (GR_GL_FUNC *BlitFramebuffer)(GLint srcX0, GLint srcY0,
+ GLint srcX1, GLint srcY1,
+ GLint dstX0, GLint dstY0,
+ GLint dstX1, GLint dstY1,
+ GLbitfield mask, GLenum filter);
+ // apple's es extension
+ GLvoid (GR_GL_FUNC *ResolveMultisampleFramebuffer)();
+
+ // IMG'e es extension
+ GLvoid (GR_GL_FUNC *FramebufferTexture2DMultisample)(GLenum target,
+ GLenum attachment,
+ GLenum textarget,
+ GLuint texture,
+ GLint level,
+ GLsizei samples);
+
+// Buffer mapping (extension in ES).
+ GLvoid* (GR_GL_FUNC *MapBuffer)(GLenum target, GLenum access);
+ GLboolean (GR_GL_FUNC *UnmapBuffer)(GLenum target);
+};
+}
+
+// FBO
+#define GR_FRAMEBUFFER 0x8D40
+#define GR_FRAMEBUFFER_COMPLETE 0x8CD5
+#define GR_COLOR_ATTACHMENT0 0x8CE0
+#define GR_FRAMEBUFFER_BINDING 0x8CA6
+#define GR_RENDERBUFFER 0x8D41
+#define GR_STENCIL_ATTACHMENT 0x8D20
+#define GR_STENCIL_INDEX8 0x8D48
+#define GR_STENCIL_INDEX16 0x8D49
+#define GR_MAX_RENDERBUFFER_SIZE 0x84E8
+#define GR_DEPTH_STENCIL_ATTACHMENT 0x821A
+#define GR_UNSIGNED_INT_24_8 0x84FA
+#define GR_DEPTH_STENCIL 0x84F9
+#define GR_RGBA8 0x8058
+#define GR_RGB565 0x8D62
+
+
+// Multisampling
+
+// IMG MAX_SAMPLES uses a different value than desktop, Apple ES extension.
+#define GR_MAX_SAMPLES 0x8D57
+#define GR_MAX_SAMPLES_IMG 0x9135
+#define GR_READ_FRAMEBUFFER 0x8CA8
+#define GR_DRAW_FRAMEBUFFER 0x8CA9
+
+// Buffer mapping
+#define GR_WRITE_ONLY 0x88B9
+#define GR_BUFFER_MAPPED 0x88BC
+
+// Palette texture
+#define GR_PALETTE8_RGBA8 0x8B91
+
+extern void GrGLInitExtensions(GrGLExts* exts);
+////////////////////////////////////////////////////////////////////////////////
+
+extern void GrGLCheckErr(const char* location, const char* call);
+
+static inline void GrGLClearErr() {
+ while (GL_NO_ERROR != glGetError()) {}
+}
+
+// GR_FORCE_GLCHECKERR can be defined by GrUserConfig.h
+#if defined(GR_FORCE_GLCHECKERR)
+ #define GR_LOCAL_CALL_CHECKERR GR_FORCE_GLCHECKERR
+#else
+ #define GR_LOCAL_CALL_CHECKERR GR_DEBUG
+#endif
+static inline void GrDebugGLCheckErr(const char* location, const char* call) {
+#if GR_LOCAL_CALL_CHECKERR
+ GrGLCheckErr(location, call);
+#endif
+}
+#undef GR_LOCAL_CALL_CHECKERR
+
+#if GR_GL_LOG_CALLS
+ extern bool gPrintGL;
+ #define GR_GL(X) gl ## X; GrDebugGLCheckErr(GR_FILE_AND_LINE_STR, #X); if (gPrintGL) GrPrintf(GR_FILE_AND_LINE_STR "GL: " #X "\n")
+ #define GR_GL_NO_ERR(X) GrGLClearErr(); gl ## X; if (gPrintGL) GrPrintf(GR_FILE_AND_LINE_STR "GL: " #X "\n")
+ #define GR_GLEXT(exts, X) exts. X; GrDebugGLCheckErr(GR_FILE_AND_LINE_STR, #X); if (gPrintGL) GrPrintf(GR_FILE_AND_LINE_STR "GL: " #X "\n")
+ #define GR_GLEXT_NO_ERR(exts, X) GrGLClearErr(); exts. X; if (gPrintGL) GrPrintf(GR_FILE_AND_LINE_STR "GL: " #X "\n")
+#else
+ #define GR_GL(X) gl ## X; GrDebugGLCheckErr(GR_FILE_AND_LINE_STR, #X)
+ #define GR_GL_NO_ERR(X) GrGLClearErr(); gl ## X
+ #define GR_GLEXT(exts, X) exts. X; GrDebugGLCheckErr(GR_FILE_AND_LINE_STR, #X)
+ #define GR_GLEXT_NO_ERR(exts, X) GrGLClearErr(); exts. X
+#endif
+
+#endif
+
diff --git a/gpu/include/GrGLIndexBuffer.h b/gpu/include/GrGLIndexBuffer.h
new file mode 100644
index 0000000000..5177b4b7f5
--- /dev/null
+++ b/gpu/include/GrGLIndexBuffer.h
@@ -0,0 +1,53 @@
+/*
+ Copyright 2010 Google Inc.
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ */
+
+
+#ifndef GrGLIndexBuffer_DEFINED
+#define GrGLIndexBuffer_DEFINED
+
+#include "GrIndexBuffer.h"
+#include "GrGLConfig.h"
+
+class GrGpuGL;
+
+class GrGLIndexBuffer : public GrIndexBuffer {
+protected:
+ GrGLIndexBuffer(GLuint id,
+ GrGpuGL* gl,
+ uint32_t sizeInBytes,
+ bool dynamic);
+public:
+ virtual ~GrGLIndexBuffer();
+
+ GLuint bufferID() const;
+
+ // overrides of GrIndexBuffer
+ virtual void abandon();
+ virtual void* lock();
+ virtual void unlock();
+ virtual bool isLocked() const;
+ virtual bool updateData(const void* src, uint32_t srcSizeInBytes);
+private:
+ GrGpuGL* fGL;
+ GLuint fBufferID;
+ void* fLockPtr;
+
+ friend class GrGpuGL;
+
+ typedef GrIndexBuffer INHERITED;
+};
+
+#endif
diff --git a/gpu/include/GrGLTexture.h b/gpu/include/GrGLTexture.h
new file mode 100644
index 0000000000..ada31512f5
--- /dev/null
+++ b/gpu/include/GrGLTexture.h
@@ -0,0 +1,166 @@
+/*
+ Copyright 2010 Google Inc.
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ */
+
+
+#ifndef GrGLTexture_DEFINED
+#define GrGLTexture_DEFINED
+
+#include "GrGLConfig.h"
+#include "GrGpu.h"
+#include "GrTexture.h"
+#include "GrRect.h"
+
+class GrGpuGL;
+class GrGLTexture;
+
+class GrGLRenderTarget : public GrRenderTarget {
+protected:
+
+ struct GLRenderTargetIDs {
+ GLuint fRTFBOID;
+ GLuint fTexFBOID;
+ GLuint fStencilRenderbufferID;
+ GLuint fMSColorRenderbufferID;
+ bool fOwnIDs;
+ };
+
+ GrGLRenderTarget(const GLRenderTargetIDs& ids,
+ const GrIRect& fViewport,
+ GrGLTexture* texture,
+ GrGpuGL* gl);
+
+ void setViewport(const GrIRect& rect) { GrAssert(rect.height() <= 0);
+ fViewport = rect;}
+
+ virtual uint32_t width() const { return fViewport.width(); }
+ virtual uint32_t height() const { return -fViewport.height(); }
+
+public:
+ virtual ~GrGLRenderTarget();
+
+ bool resolveable() const { return fRTFBOID != fTexFBOID; }
+ bool needsResolve() const { return fNeedsResolve; }
+ void setDirty(bool dirty) { fNeedsResolve = resolveable() && dirty; }
+
+ GLuint renderFBOID() const { return fRTFBOID; }
+ GLuint textureFBOID() const { return fTexFBOID; }
+
+ const GrIRect& viewport() const { return fViewport; }
+ void abandon();
+
+private:
+ GrGpuGL* fGL;
+ GLuint fRTFBOID;
+ GLuint fTexFBOID;
+ GLuint fStencilRenderbufferID;
+ GLuint fMSColorRenderbufferID;
+
+ // Should this object delete IDs when it is destroyed or does someone
+ // else own them.
+ bool fOwnIDs;
+
+ // If there separate Texture and RenderTarget FBO IDs then the rendertarget
+ // must be resolved to the texture FBO before it is used as a texture.
+ bool fNeedsResolve;
+
+ // when we switch to this rendertarget we want to set the viewport to
+ // only render to to content area (as opposed to the whole allocation) and
+ // we want the rendering to be at top left (GL has origin in bottom left)
+ GrIRect fViewport;
+
+ friend class GrGpuGL;
+ friend class GrGLTexture;
+
+ typedef GrRenderTarget INHERITED;
+};
+
+class GrGLTexture : public GrTexture {
+public:
+ enum Orientation {
+ kBottomUp_Orientation,
+ kTopDown_Orientation,
+ };
+
+protected:
+ struct GLTextureDesc {
+ uint32_t fContentWidth;
+ uint32_t fContentHeight;
+ uint32_t fAllocWidth;
+ uint32_t fAllocHeight;
+ PixelConfig fFormat;
+ GLuint fTextureID;
+ GLenum fUploadFormat;
+ GLenum fUploadByteCount;
+ GLenum fUploadType;
+ Orientation fOrientation;
+ };
+ typedef GrGLRenderTarget::GLRenderTargetIDs GLRenderTargetIDs;
+ GrGLTexture(const GLTextureDesc& textureDesc,
+ const GLRenderTargetIDs& rtIDs,
+ GrGpuGL* gl);
+
+public:
+ virtual ~GrGLTexture();
+
+ // overloads of GrTexture
+ virtual void abandon();
+ virtual bool isRenderTarget() const;
+ virtual GrRenderTarget* asRenderTarget();
+ virtual void removeRenderTarget();
+ virtual void uploadTextureData(uint32_t x,
+ uint32_t y,
+ uint32_t width,
+ uint32_t height,
+ const void* srcData);
+ virtual intptr_t getTextureHandle();
+
+ const GrSamplerState& samplerState() const { return fSamplerState; }
+ void setSamplerState(const GrSamplerState& state)
+ { fSamplerState = state; }
+ GLuint textureID() const { return fTextureID; }
+
+ GLenum uploadFormat() const { return fUploadFormat; }
+ GLenum uploadByteCount() const { return fUploadByteCount; }
+ GLenum uploadType() const { return fUploadType; }
+
+ // Ganesh assumes texture coordinates have their origin
+ // in the top-left corner of the image. OpenGL, however,
+ // has the origin in the lower-left corner. For content that
+ // is loaded by Ganesh we just push the content "upside down"
+ // (by GL's understanding of the world ) in glTex*Image and the
+ // addressing just works out. However, content generated by GL
+ // (FBO or externally imported texture) will be updside down
+ // and it is up to the GrGpuGL derivative to handle y-mirroing.
+ Orientation orientation() const { return fOrientation; }
+
+private:
+ GrSamplerState fSamplerState;
+ GLuint fTextureID;
+ GLenum fUploadFormat;
+ GLenum fUploadByteCount;
+ GLenum fUploadType;
+ Orientation fOrientation;
+ GrGLRenderTarget* fRenderTarget;
+ GrGpuGL* fGpuGL;
+
+ static const GLenum gWrapMode2GLWrap[];
+
+ friend class GrGpuGL;
+
+ typedef GrTexture INHERITED;
+};
+
+#endif
diff --git a/gpu/include/GrGLVertexBuffer.h b/gpu/include/GrGLVertexBuffer.h
new file mode 100644
index 0000000000..6b99f57e5f
--- /dev/null
+++ b/gpu/include/GrGLVertexBuffer.h
@@ -0,0 +1,55 @@
+/*
+ Copyright 2010 Google Inc.
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ */
+
+
+#ifndef GrGLVertexBuffer_DEFINED
+#define GrGLVertexBuffer_DEFINED
+
+#include "GrVertexBuffer.h"
+#include "GrGLConfig.h"
+
+class GrGpuGL;
+
+class GrGLVertexBuffer : public GrVertexBuffer {
+protected:
+ GrGLVertexBuffer(GLuint id,
+ GrGpuGL* gl,
+ uint32_t sizeInBytes,
+ bool dynamic);
+
+public:
+ virtual ~GrGLVertexBuffer();
+
+ // overrides of GrVertexBuffer
+ virtual void abandon();
+ virtual void* lock();
+ virtual void unlock();
+ virtual bool isLocked() const;
+ virtual bool updateData(const void* src, uint32_t srcSizeInBytes);
+
+ GLuint bufferID() const;
+
+private:
+ GrGpuGL* fGL;
+ GLuint fBufferID;
+ void* fLockPtr;
+
+ friend class GrGpuGL;
+
+ typedef GrVertexBuffer INHERITED;
+};
+
+#endif
diff --git a/gpu/include/GrGlyph.h b/gpu/include/GrGlyph.h
new file mode 100644
index 0000000000..4a3b3072c7
--- /dev/null
+++ b/gpu/include/GrGlyph.h
@@ -0,0 +1,89 @@
+/*
+ Copyright 2010 Google Inc.
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ */
+
+
+#ifndef GrGlyph_DEFINED
+#define GrGlyph_DEFINED
+
+#include "GrPath.h"
+#include "GrRect.h"
+
+class GrAtlas;
+
+/* Need this to be quad-state:
+ - complete w/ image
+ - just metrics
+ - failed to get image, but has metrics
+ - failed to get metrics
+ */
+struct GrGlyph {
+ typedef uint32_t PackedID;
+
+ GrAtlas* fAtlas;
+ GrPath* fPath;
+ PackedID fPackedID;
+ GrIRect16 fBounds;
+ GrIPoint16 fAtlasLocation;
+
+ void init(GrGlyph::PackedID packed, const GrIRect& bounds) {
+ fAtlas = NULL;
+ fPath = NULL;
+ fPackedID = packed;
+ fBounds.set(bounds);
+ fAtlasLocation.set(0, 0);
+ }
+
+ void free() {
+ if (fPath) {
+ delete fPath;
+ fPath = NULL;
+ }
+ }
+
+ int width() const { return fBounds.width(); }
+ int height() const { return fBounds.height(); }
+ bool isEmpty() const { return fBounds.isEmpty(); }
+ uint16_t glyphID() const { return UnpackID(fPackedID); }
+
+ ///////////////////////////////////////////////////////////////////////////
+
+ static inline unsigned ExtractSubPixelBitsFromFixed(GrFixed pos) {
+ // two most significant fraction bits from fixed-point
+ return (pos >> 14) & 3;
+ }
+
+ static inline PackedID Pack(uint16_t glyphID, GrFixed x, GrFixed y) {
+ x = ExtractSubPixelBitsFromFixed(x);
+ y = ExtractSubPixelBitsFromFixed(y);
+ return (x << 18) | (y << 16) | glyphID;
+ }
+
+ static inline GrFixed UnpackFixedX(PackedID packed) {
+ return ((packed >> 18) & 3) << 14;
+ }
+
+ static inline GrFixed UnpackFixedY(PackedID packed) {
+ return ((packed >> 16) & 3) << 14;
+ }
+
+ static inline uint16_t UnpackID(PackedID packed) {
+ return (uint16_t)packed;
+ }
+};
+
+
+#endif
+
diff --git a/gpu/include/GrGpu.h b/gpu/include/GrGpu.h
new file mode 100644
index 0000000000..f1fdf01d50
--- /dev/null
+++ b/gpu/include/GrGpu.h
@@ -0,0 +1,446 @@
+/*
+ Copyright 2010 Google Inc.
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ */
+
+
+#ifndef GrGpu_DEFINED
+#define GrGpu_DEFINED
+
+#include "GrRect.h"
+#include "GrRefCnt.h"
+#include "GrDrawTarget.h"
+#include "GrGpuVertex.h"
+#include "GrTexture.h"
+#include "GrMemory.h"
+
+
+class GrGpu : public GrDrawTarget {
+
+public:
+ /**
+ * Possible 3D APIs that may be used by Ganesh.
+ */
+ enum Engine {
+ kOpenGL_Shaders_Engine,
+ kOpenGL_Fixed_Engine,
+ kDirect3D9_Engine
+ };
+
+ /**
+ * Platform specific 3D context.
+ * For
+ * kOpenGL_Shaders_Engine use NULL
+ * kOpenGL_Fixed_Engine use NULL
+ * kDirect3D9_Engine use an IDirect3DDevice9*
+ */
+ typedef void* Platform3DContext;
+
+ /**
+ * Create an instance of GrGpu that matches the specified Engine backend.
+ * If the requested engine is not supported (at compile-time or run-time)
+ * this returns NULL.
+ */
+ static GrGpu* Create(Engine, Platform3DContext context3D);
+
+ /**
+ * Describes levels of support for non-power-of-two textures.
+ */
+ enum NPOTTextureTypes {
+ /**
+ * no support for NPOT textures
+ */
+ kNone_NPOTTextureType,
+ /**
+ * only clamp is supported for textures
+ */
+ kNoRepeat_NPOTTextureType,
+ /**
+ * no texture restrictions at all, but rendertargets must be POW2
+ */
+ kNonRendertarget_NPOTTextureType,
+ /**
+ * no POW2 restrictions at all
+ */
+ kFull_NPOTTextureType
+ };
+
+ /**
+ * Used to control the level of antialiasing available for a rendertarget.
+ * Anti-alias quality levels depend on the underlying API/GPU capabilities.
+ */
+ enum AALevels {
+ kNone_AALevel, //<! No antialiasing available.
+ kLow_AALevel, //<! Low quality antialiased rendering. Actual
+ // interpretation is platform-dependent.
+ kMed_AALevel, //<! Medium quality antialiased rendering. Actual
+ // interpretation is platform-dependent.
+ kHigh_AALevel, //<! High quality antialiased rendering. Actual
+ // interpretation is platform-dependent.
+ };
+
+
+ /**
+ * Optional bitfield flags that can be passed to createTexture.
+ */
+ enum TextureFlags {
+ kRenderTarget_TextureFlag = 0x1, //<! Creates a texture that can be
+ // rendered to by calling
+ // GrGpu::setRenderTarget() with
+ // GrTexture::asRenderTarget().
+ kNoPathRendering_TextureFlag = 0x2, //<! If the texture is used as a
+ // rendertarget but paths will not
+ // be rendered to it.
+ kDynamicUpdate_TextureFlag = 0x4 //!< Hint that the CPU may modify
+ // this texture after creation
+ };
+
+ enum {
+ /**
+ * For Index8 pixel config, the colortable must be 256 entries
+ */
+ kColorTableSize = 256 * sizeof(GrColor)
+ };
+ /**
+ * Describes a texture to be created.
+ */
+ struct TextureDesc {
+ uint32_t fFlags; //!< bitfield of TextureFlags
+ GrGpu::AALevels fAALevel;//!< The level of antialiasing available
+ // for a rendertarget texture. Only
+ // flags contains
+ // kRenderTarget_TextureFlag.
+ uint32_t fWidth; //!< Width of the texture
+ uint32_t fHeight; //!< Height of the texture
+ GrTexture::PixelConfig fFormat; //!< Format of source data of the
+ // texture. Not guaraunteed to be the
+ // same as internal format used by
+ // 3D API.
+ };
+
+ /**
+ * Gpu usage statistics.
+ */
+ struct Stats {
+ uint32_t fVertexCnt; //<! Number of vertices drawn
+ uint32_t fIndexCnt; //<! Number of indices drawn
+ uint32_t fDrawCnt; //<! Number of draws
+
+ uint32_t fProgChngCnt;//<! Number of program changes (N/A for fixed)
+
+ /*
+ * Number of times the texture is set in 3D API
+ */
+ uint32_t fTextureChngCnt;
+ /*
+ * Number of times the render target is set in 3D API
+ */
+ uint32_t fRenderTargetChngCnt;
+ /*
+ * Number of textures created (includes textures that are rendertargets).
+ */
+ uint32_t fTextureCreateCnt;
+ /*
+ * Number of rendertargets created.
+ */
+ uint32_t fRenderTargetCreateCnt;
+ };
+
+ ////////////////////////////////////////////////////////////////////////////
+
+ GrGpu();
+ virtual ~GrGpu();
+
+ /**
+ * The GrGpu object normally assumes that no outsider is setting state
+ * within the underlying 3D API's context/device/whatever. This call informs
+ * the GrGpu that the state was modified and it should resend. Shouldn't
+ * be called frequently for good performance.
+ */
+ virtual void resetContext();
+
+ void unimpl(const char[]);
+
+ /**
+ * Creates a texture object
+ *
+ * @param desc describes the texture to be created.
+ * @param srcData texel data to load texture. Begins with full-size
+ * palette data for paletted textures. Contains width*
+ * height texels. If NULL texture data is uninitialized.
+ *
+ * @return The texture object if successful, otherwise NULL.
+ */
+ virtual GrTexture* createTexture(const TextureDesc& desc,
+ const void* srcData, size_t rowBytes) = 0;
+ /**
+ * Wraps an externally-created rendertarget in a GrRenderTarget.
+ * @param platformRenderTarget handle to the the render target in the
+ * underlying 3D API. Interpretation depends on
+ * GrGpu subclass in use.
+ * @param width width of the render target
+ * @param height height of the render target
+ */
+ virtual GrRenderTarget* createPlatformRenderTarget(
+ intptr_t platformRenderTarget,
+ int width, int height) = 0;
+
+ /**
+ * Creates a vertex buffer.
+ *
+ * @param size size in bytes of the vertex buffer
+ * @param dynamic hints whether the data will be frequently changed
+ * by either GrVertexBuffer::lock or
+ * GrVertexBuffer::updateData.
+ *
+ * @return The vertex buffer if successful, otherwise NULL.
+ */
+ virtual GrVertexBuffer* createVertexBuffer(uint32_t size, bool dynamic) = 0;
+
+ /**
+ * Creates an index buffer.
+ *
+ * @param size size in bytes of the index buffer
+ * @param dynamic hints whether the data will be frequently changed
+ * by either GrIndexBuffer::lock or
+ * GrIndexBuffer::updateData.
+ *
+ * @return The index buffer if successful, otherwise NULL.
+ */
+ virtual GrIndexBuffer* createIndexBuffer(uint32_t size, bool dynamic) = 0;
+
+ /**
+ * Gets the default render target. This is the render target set in the
+ * 3D API at the time the GrGpu was created.
+ */
+ virtual GrRenderTarget* defaultRenderTarget() = 0;
+
+ /**
+ * At construction time the GrGpu infers the render target and viewport from
+ * the state of the underlying 3D API. However, a platform-specific resize
+ * event may occur.
+ * @param width new width of the default rendertarget
+ * @param height new height of the default rendertarget
+ */
+ virtual void setDefaultRenderTargetSize(uint32_t width, uint32_t height) = 0;
+
+ /**
+ * Erase the entire render target, ignoring any clips/scissors.
+ *
+ * This is issued to the GPU driver immediately.
+ */
+ virtual void eraseColor(GrColor color) = 0;
+
+ /**
+ * Are 8 bit paletted textures supported.
+ *
+ * @return true if 8bit palette textures are supported, false otherwise
+ */
+ bool supports8BitPalette() const { return f8bitPaletteSupport; }
+
+ /**
+ * If single stencil pass winding is supported then one stencil pass
+ * (kWindingStencil1_PathPass) is required to do winding rule path filling
+ * (or inverse winding rule). Otherwise, two passes are required
+ * (kWindingStencil1_PathPass followed by kWindingStencil2_PathPass).
+ *
+ * @return true if only a single stencil pass is needed.
+ */
+ bool supportsSingleStencilPassWinding() const
+ { return fSingleStencilPassForWinding; }
+
+ /**
+ * Checks whether locking vertex and index buffers is supported.
+ *
+ * @return true if locking is supported.
+ */
+ bool supportsBufferLocking() const { return fBufferLockSupport; }
+
+ /**
+ * Gets the minimum width of a render target. If a texture/rt is created
+ * with a width less than this size the GrGpu object will clamp it to this
+ * value.
+ */
+ int minRenderTargetWidth() const { return fMinRenderTargetWidth; }
+
+ /**
+ * Gets the minimum width of a render target. If a texture/rt is created
+ * with a height less than this size the GrGpu object will clamp it to this
+ * value.
+ */
+ int minRenderTargetHeight() const { return fMinRenderTargetHeight; }
+
+ /**
+ * Retrieves the level of NPOT texture support. Regardless of support level
+ * NPOT textures can always be created, but internally they may be imbedded
+ * in a POT texture. An exception is paletted textures which must be
+ * specified as a POT when npotTextureSupport() is not Full.
+ *
+ * @return the level of NPOT texture support.
+ */
+ NPOTTextureTypes npotTextureSupport() const { return fNPOTTextureSupport; }
+
+ // GrDrawTarget overrides
+ virtual void drawIndexed(PrimitiveType type,
+ uint32_t startVertex,
+ uint32_t startIndex,
+ uint32_t vertexCount,
+ uint32_t indexCount);
+
+ virtual void drawNonIndexed(PrimitiveType type,
+ uint32_t startVertex,
+ uint32_t vertexCount);
+
+ /**
+ * Determines if blend is effectively disabled.
+ *
+ * @return true if blend can be disabled without changing the rendering
+ * result given the current state including the vertex layout specified
+ * with the vertex source.
+ */
+ bool canDisableBlend() const;
+
+ /**
+ * Returns an index buffer that can be used to render quads.
+ * Indices are 0, 1, 2, 0, 2, 3, etc.
+ * Draw with kTriangles_PrimitiveType
+ */
+ const GrIndexBuffer* quadIndexBuffer() const;
+ /**
+ * Gets the number of quads that can be rendered using quadIndexBuffer.
+ */
+ int maxQuadsInIndexBuffer() const;
+
+ /**
+ * Ensures that the current render target is actually set in the
+ * underlying 3D API. Used when client wants to use 3D API to directly
+ * render to the RT.
+ */
+ virtual void forceRenderTargetFlush() = 0;
+
+ virtual bool readPixels(int left, int top, int width, int height,
+ GrTexture::PixelConfig, void* buffer) = 0;
+
+
+ const Stats& getStats() const;
+ void resetStats();
+ void printStats() const;
+
+protected:
+ /**
+ * Extensions to GrDrawTarget::StencilPass to implement stencil clipping
+ */
+ enum GpuStencilPass {
+ kSetClip_StencilPass = kDrawTargetCount_StencilPass,
+ /* rendering a hard clip to the stencil
+ buffer. Subsequent draws with other
+ StencilPass values will be clipped
+ if kStencilClip_StateBit is set. */
+ kGpuCount_StencilPass
+ };
+
+ /**
+ * Extensions to GrDrawTarget::StateBits to implement stencil clipping
+ */
+ struct ClipState {
+ bool fClipInStencil;
+ bool fClipIsDirty;
+ GrRenderTarget* fStencilClipTarget;
+ } fClipState;
+
+ virtual void clipWillChange(const GrClip& clip);
+ bool setupClipAndFlushState(PrimitiveType type);
+
+ struct BoundsState {
+ bool fScissorEnabled;
+ GrIRect fScissorRect;
+ GrIRect fViewportRect;
+ };
+
+ // defaults to false, subclass can set true to support palleted textures
+ bool f8bitPaletteSupport;
+
+ // defaults to false, subclass can set higher support level
+ NPOTTextureTypes fNPOTTextureSupport;
+
+ // True if only one stencil pass is required to implement the winding path
+ // fill rule. Subclass responsible for setting this value.
+ bool fSingleStencilPassForWinding;
+
+ // set by subclass to true if index and vertex buffers can be locked, false
+ // otherwise.
+ bool fBufferLockSupport;
+
+ // set by subclass
+ int fMinRenderTargetWidth;
+ int fMinRenderTargetHeight;
+
+ // overridden by API specific GrGpu-derived class to perform the draw call.
+ virtual void drawIndexedHelper(PrimitiveType type,
+ uint32_t startVertex,
+ uint32_t startIndex,
+ uint32_t vertexCount,
+ uint32_t indexCount) = 0;
+
+ virtual void drawNonIndexedHelper(PrimitiveType type,
+ uint32_t vertexCount,
+ uint32_t numVertices) = 0;
+
+ // called to program the vertex data, indexCount will be 0 if drawing non-
+ // indexed geometry.
+ virtual void setupGeometry(uint32_t startVertex,
+ uint32_t startIndex,
+ uint32_t vertexCount,
+ uint32_t indexCount) = 0;
+
+
+ // The GrGpu typically records the clients requested state and then flushes
+ // deltas from previous state at draw time. This function does the
+ // API-specific flush of the state
+ // returns false if current state is unsupported.
+ virtual bool flushGraphicsState(PrimitiveType type) = 0;
+
+ // Sets the scissor rect, or disables if rect is NULL.
+ virtual void flushScissor(const GrIRect* rect) = 0;
+
+ // GrGpu subclass removes the clip from the stencil buffer
+ virtual void eraseStencilClip() = 0;
+
+ // GrDrawTarget overrides
+ virtual bool acquireGeometryHelper(GrVertexLayout vertexLayout,
+ void** vertices,
+ void** indices);
+ virtual void releaseGeometryHelper();
+
+private:
+ mutable GrIndexBuffer* fQuadIndexBuffer; // mutable so it can be
+ // created on-demand
+
+ static const int MAX_VERTEX_SIZE = GR_CT_MAX(2*sizeof(GrPoint) + sizeof(GrColor),
+ 2*sizeof(GrGpuTextVertex));
+ static const int VERTEX_STORAGE = 16 * MAX_VERTEX_SIZE;
+ static const int INDEX_STORAGE = 32 * sizeof(uint16_t);
+
+protected:
+ GrAutoSMalloc<VERTEX_STORAGE> fVertices;
+ GrAutoSMalloc<INDEX_STORAGE> fIndices;
+
+ Stats fStats;
+
+private:
+ typedef GrRefCnt INHERITED;
+};
+
+#endif
+
diff --git a/gpu/include/GrGpuD3D9.h b/gpu/include/GrGpuD3D9.h
new file mode 100644
index 0000000000..c3d3e1a829
--- /dev/null
+++ b/gpu/include/GrGpuD3D9.h
@@ -0,0 +1,259 @@
+/*
+ Copyright 2010 Google Inc.
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ */
+
+
+#ifndef GrGpuD3D9_DEFINED
+#define GrGpuD3D9_DEFINED
+
+#include <Windows.h>
+#include <d3d9.h>
+
+#include "GrGpu.h"
+
+class GrD3D9VertexBuffer;
+class GrD3D9IndexBuffer;
+class GrD3D9Texture;
+
+// For D3D9 GrRenderTarget casts to a (GrD3D9RenderTarget*)
+struct GrD3D9RenderTarget {
+ IDirect3DSurface9* fColor;
+ IDirect3DSurface9* fStencil;
+ bool fClearStencil;
+};
+
+// GrGpu implementation for D3D9 fixed pipeline.
+// Known needed improvements:
+// vertex/index buffers need to be better managed:
+// use no_overwrite and walk down VB/IB until reach end and wrap
+// take advantage of the redrawHint and don't recopy vertex/idx data
+// User created vertex buffers must have position Z values
+// (required for fixed pipeline) but there is no way to communicate
+// this now
+// We create a temporary sysmem surface for each texture update.
+// split this out into fixed/shader subclasses (use vdecls for shaders)
+class GrGpuD3D9 : public GrGpu {
+public:
+ GrGpuD3D9(IDirect3DDevice9* device);
+ virtual ~GrGpuD3D9();
+
+ // overrides from GrGpu
+ virtual GrTexture* createTexture(const TextureDesc& desc,
+ const void* srcData);
+ virtual GrVertexBuffer* createVertexBuffer(uint32_t size, bool dynamic);
+ virtual GrIndexBuffer* createIndexBuffer(uint32_t size, bool dynamic);
+
+ virtual void eraseColor(GrColor color);
+ virtual void eraseStencil();
+
+protected:
+ // overrides from GrGpu
+ virtual bool flushGraphicsState(PrimitiveTypes type);
+ virtual void drawIndexArrayApi(PrimitiveTypes type,
+ int baseVertex,
+ int vertexCount,
+ int indexCount,
+ const uint16_t* indexArray,
+ bool redrawHint);
+ virtual void drawIndexBufferApi(PrimitiveTypes type,
+ int baseVertex,
+ int startIndex,
+ int vertexCount,
+ int indexCount,
+ GrIndexBuffer* indexBuffer,
+ bool redrawHint);
+ virtual void drawNonIndexedApi(PrimitiveTypes type,
+ int baseVertex,
+ int indexCount,
+ bool redrawHint);
+ virtual void flushScissor();
+
+private:
+
+ // baseVertex may be modified while setting up the stage
+ GrD3D9VertexBuffer* setupVBufferStage(int vsize, int* baseVertex,
+ int vertexCount, DrawModes mode);
+ GrD3D9IndexBuffer* setupIBufferStage(int* startIndex, int indexCount,
+ const uint16_t* indices);
+ static int vertexSize(int vertFlagBits, GrGpu::DrawModes mode);
+ static bool positionsOnly(int vertFlagBits);
+
+ // notify callbacks to update state tracking when related
+ // objects are bound to the device or deleted outside of the class
+ void notifyVertexBufferBind(GrD3D9VertexBuffer* buffer);
+ void notifyVertexBufferDelete(GrD3D9VertexBuffer* buffer);
+ void notifyIndexBufferBind(GrD3D9IndexBuffer* buffer);
+ void notifyIndexBufferDelete(GrD3D9IndexBuffer* buffer);
+ void notifyTextureDelete(GrD3D9Texture* texture);
+ void notifyTextureRemoveRenderTarget(GrD3D9Texture* texture);
+
+ IDirect3DSurface9* createStencil(uint32_t width,
+ uint32_t height,
+ D3DMULTISAMPLE_TYPE msType,
+ DWORD msQual);
+
+ void setRenderTargetImm();
+
+ friend class GrD3D9VertexBuffer;
+ friend class GrD3D9IndexBuffer;
+ friend class GrD3D9Texture;
+
+ GrIndexBuffer* fLastIndexBuffer;
+
+ // used to track the COLORARG1 value for tex stage 0
+ // needs to use ALPHAREPLICATE when using alpha-only textures
+ DWORD fLastColorArg1;
+
+ IDirect3DDevice9* fDevice;
+ // We may use Ex functionality if this is a Ex device
+ IDirect3DDevice9Ex* fDeviceEx;
+
+ enum VertDecls {
+ kInvalid_VertDecl = -1,
+ kPosOnly_VertDecl = 0,
+ kTex_VertDecl,
+ kColors_VertDecl,
+ kTexAndColors_VertDecl,
+ kPosAsTex_VertDecl,
+ kPosAsTexAndColors_VertDecl,
+ kVertDeclCount
+ };
+
+ static const VertDecls gVertFlags2VertDeclIdx[];
+ static const DWORD gDeclToFVFs[];
+ static const DWORD gTextFVF;
+
+ DWORD fLastVertFVF;
+
+ bool fLastBlendOff;
+
+ // D3D allows user pointers in place of buffers for vertex/index data
+ // but it doesn't allow:
+ // -multiple streams (non-interleaved) ~ this will be resolved when we
+ // go AoS with our verts
+ // -mixing user pointer verts with index buffer (or vice versa)
+ // So we use these staging buffers
+ GrD3D9VertexBuffer* fStageVBuffer;
+ GrD3D9IndexBuffer* fStageIBuffer;
+
+ // did we use texture coordinate generation at the last flush
+ bool fLastTexGen;
+
+ GrD3D9RenderTarget fDefaultRenderTarget;
+
+ // We use texture stage 0 to set a constant color
+ // D3D disables the stage if NULL is bound (even when the ops don't
+ // reference the texture). So we have a 1x1 dummy texture that
+ // gets set when drawing constant color with no texture
+ GrD3D9Texture* fDummyTexture;
+};
+
+class GrD3D9Texture : public GrTexture {
+protected:
+ GrD3D9Texture(uint32_t width,
+ uint32_t height,
+ PixelConfig config,
+ IDirect3DTexture9* texture,
+ IDirect3DSurface9* stencil,
+ bool clearStencil,
+ GrGpuD3D9* gpuD3D9);
+public:
+ virtual ~GrD3D9Texture();
+
+ // overloads of GrTexture
+ virtual void abandon();
+ virtual bool isRenderTarget();
+ virtual GrRenderTarget* asRenderTarget()
+ { return (GrRenderTarget*) &fRenderTarget; }
+ virtual void removeRenderTarget();
+ virtual void uploadTextureData(uint32_t x,
+ uint32_t y,
+ uint32_t width,
+ uint32_t height,
+ const void* srcData);
+ IDirect3DTexture9* texture() const { return fTexture; }
+ IDirect3DSurface9* stencil() const { return fStencil; }
+ D3DFORMAT format() const { return fDesc.Format; }
+private:
+ IDirect3DTexture9* fTexture;
+ GrD3D9RenderTarget fRenderTarget;
+ IDirect3DSurface9* fStencil;
+ D3DSURFACE_DESC fDesc;
+ GrGpuD3D9* fGpuD3D9;
+
+ friend class GrGpuD3D9;
+
+ typedef GrTexture INHERITED;
+};
+
+class GrD3D9VertexBuffer : public GrVertexBuffer {
+protected:
+ GrD3D9VertexBuffer(uint32_t size,
+ bool dynamic,
+ IDirect3DVertexBuffer9* vbuffer,
+ GrGpuD3D9* gpuD3D9);
+public:
+ virtual ~GrD3D9VertexBuffer();
+
+ IDirect3DVertexBuffer9* buffer() const { return fBuffer; }
+
+ // overrides of GrVertexBuffer
+ virtual void abandon();
+ virtual void* lock();
+ virtual void unlock();
+ virtual bool isLocked();
+ virtual bool updateData(const void* src, uint32_t srcSizeInBytes);
+
+private:
+ IDirect3DVertexBuffer9* fBuffer;
+ D3DVERTEXBUFFER_DESC fDesc;
+ bool fLocked;
+ GrGpuD3D9* fGpuD3D9;
+
+ friend class GrGpuD3D9;
+
+ typedef GrVertexBuffer INHERITED;
+};
+
+class GrD3D9IndexBuffer : public GrIndexBuffer {
+protected:
+ GrD3D9IndexBuffer(uint32_t size,
+ bool dynamic,
+ IDirect3DIndexBuffer9* vbuffer,
+ GrGpuD3D9* gpuD3D9);
+public:
+ virtual ~GrD3D9IndexBuffer();
+
+ IDirect3DIndexBuffer9* buffer() const { return fBuffer; }
+
+ // overrides of GrIndexBuffer
+ virtual void abandon();
+ virtual void* lock();
+ virtual void unlock();
+ virtual bool isLocked();
+ virtual bool updateData(const void* src, uint32_t srcSizeInBytes);
+private:
+ IDirect3DIndexBuffer9* fBuffer;
+ D3DINDEXBUFFER_DESC fDesc;
+ bool fLocked;
+ GrGpuD3D9* fGpuD3D9;
+
+ friend class GrGpuD3D9;
+
+ typedef GrIndexBuffer INHERITED;
+};
+
+#endif
+
diff --git a/gpu/include/GrGpuVertex.h b/gpu/include/GrGpuVertex.h
new file mode 100644
index 0000000000..1e3293a2ba
--- /dev/null
+++ b/gpu/include/GrGpuVertex.h
@@ -0,0 +1,104 @@
+/*
+ Copyright 2010 Google Inc.
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ */
+
+
+#ifndef GrGpuVertex_DEFINED
+#define GrGpuVertex_DEFINED
+
+#include "GrGLConfig.h"
+#include "GrPoint.h"
+
+#if GR_TEXT_SCALAR_IS_USHORT
+ typedef uint16_t GrTextScalar;
+ #define GrIntToTextScalar(x) ((uint16_t)x)
+ #define GrFixedToTextScalar(x) (x)
+#elif GR_TEXT_SCALAR_IS_FIXED
+ typedef GrFixed GrTextScalar;
+ #define GrIntToTextScalar(x) GrIntToFixed(x)
+ #define GrFixedToTextScalar(x) (x)
+#elif GR_TEXT_SCALAR_IS_FLOAT
+ typedef float GrTextScalar;
+ #define GrIntToTextScalar(x) ((GrTextScalar)x)
+ #define GrFixedToTextScalar(x) GrFixedToFloat(x)
+#else
+ #error "Text scalar type not defined"
+#endif
+
+// text has its own vertex class, since it may want to be in fixed point (given)
+// that it starts with all integers) even when the default vertices are floats
+struct GrGpuTextVertex {
+ GrTextScalar fX;
+ GrTextScalar fY;
+
+ void set(GrTextScalar x, GrTextScalar y) {
+ fX = x;
+ fY = y;
+ }
+
+ void setI(int x, int y) {
+ fX = GrIntToTextScalar(x);
+ fY = GrIntToTextScalar(y);
+ }
+
+ void setX(GrFixed x, GrFixed y) {
+ fX = GrFixedToTextScalar(x);
+ fY = GrFixedToTextScalar(y);
+ }
+
+ // rect fan is counter-clockwise
+
+ void setRectFan(GrTextScalar l, GrTextScalar t, GrTextScalar r,
+ GrTextScalar b) {
+ GrGpuTextVertex* v = this;
+ v[0].set(l, t);
+ v[1].set(l, b);
+ v[2].set(r, b);
+ v[3].set(r, t);
+ }
+
+ void setIRectFan(int l, int t, int r, int b) {
+ this->setRectFan(GrIntToTextScalar(l), GrIntToTextScalar(t),
+ GrIntToTextScalar(r), GrIntToTextScalar(b));
+ }
+
+ void setIRectFan(int l, int t, int r, int b, size_t stride) {
+ GrAssert(stride > sizeof(GrGpuTextVertex));
+ char* v = (char*)this;
+ ((GrGpuTextVertex*)(v + 0*stride))->setI(l, t);
+ ((GrGpuTextVertex*)(v + 1*stride))->setI(l, b);
+ ((GrGpuTextVertex*)(v + 2*stride))->setI(r, b);
+ ((GrGpuTextVertex*)(v + 3*stride))->setI(r, t);
+ }
+
+ // counter-clockwise fan
+ void setXRectFan(GrFixed l, GrFixed t, GrFixed r, GrFixed b) {
+ this->setRectFan(GrFixedToTextScalar(l), GrFixedToTextScalar(t),
+ GrFixedToTextScalar(r), GrFixedToTextScalar(b));
+ }
+
+ void setXRectFan(GrFixed l, GrFixed t, GrFixed r, GrFixed b, size_t stride) {
+ GrAssert(stride > sizeof(GrGpuTextVertex));
+ char* v = (char*)this;
+ ((GrGpuTextVertex*)(v + 0*stride))->setX(l, t);
+ ((GrGpuTextVertex*)(v + 1*stride))->setX(l, b);
+ ((GrGpuTextVertex*)(v + 2*stride))->setX(r, b);
+ ((GrGpuTextVertex*)(v + 3*stride))->setX(r, t);
+ }
+
+};
+
+#endif
+
diff --git a/gpu/include/GrIPoint.h b/gpu/include/GrIPoint.h
new file mode 100644
index 0000000000..b979a09340
--- /dev/null
+++ b/gpu/include/GrIPoint.h
@@ -0,0 +1,35 @@
+/*
+ Copyright 2010 Google Inc.
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ */
+
+
+#ifndef GrIPoint_DEFINED
+#define GrIPoint_DEFINED
+
+#include "GrTypes.h"
+
+struct GrIPoint {
+public:
+ int32_t fX, fY;
+
+ GrIPoint(int32_t x, int32_t y) : fX(x), fY(y) {}
+
+ void set(int32_t x, int32_t y) {
+ fX = x;
+ fY = y;
+ }
+};
+
+#endif
diff --git a/gpu/include/GrInOrderDrawBuffer.h b/gpu/include/GrInOrderDrawBuffer.h
new file mode 100644
index 0000000000..805861ada1
--- /dev/null
+++ b/gpu/include/GrInOrderDrawBuffer.h
@@ -0,0 +1,131 @@
+/*
+ Copyright 2010 Google Inc.
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ */
+
+
+#ifndef GrInOrderDrawBuffer_DEFINED
+#define GrInOrderDrawBuffer_DEFINED
+
+#include "GrDrawTarget.h"
+#include "GrAllocPool.h"
+#include "GrAllocator.h"
+#include "GrClip.h"
+
+class GrVertexBufferAllocPool;
+
+// TODO: don't save clip per draw
+class GrInOrderDrawBuffer : public GrDrawTarget {
+public:
+
+ GrInOrderDrawBuffer(GrVertexBufferAllocPool* pool = NULL);
+
+ virtual ~GrInOrderDrawBuffer();
+
+ void initializeDrawStateAndClip(const GrDrawTarget& target);
+
+ virtual void drawIndexed(PrimitiveType type,
+ uint32_t startVertex,
+ uint32_t startIndex,
+ uint32_t vertexCount,
+ uint32_t indexCount);
+
+ virtual void drawNonIndexed(PrimitiveType type,
+ uint32_t startVertex,
+ uint32_t vertexCount);
+
+ virtual bool geometryHints(GrVertexLayout vertexLayout,
+ int32_t* vertexCount,
+ int32_t* indexCount) const;
+
+ void reset();
+
+ void playback(GrDrawTarget* target);
+
+private:
+
+ struct Draw {
+ PrimitiveType fType;
+ uint32_t fStartVertex;
+ uint32_t fStartIndex;
+ uint32_t fVertexCount;
+ uint32_t fIndexCount;
+ bool fStateChange;
+ GrVertexLayout fVertexLayout;
+ bool fUseVertexBuffer;
+ bool fClipChanged;
+ union {
+ const GrVertexBuffer* fVertexBuffer;
+ const void* fVertexArray;
+ };
+ bool fUseIndexBuffer;
+ union {
+ const GrIndexBuffer* fIndexBuffer;
+ const void* fIndexArray;
+ };
+ };
+
+ virtual bool acquireGeometryHelper(GrVertexLayout vertexLayout,
+ void** vertices,
+ void** indices);
+ virtual void releaseGeometryHelper();
+ virtual void clipWillChange(const GrClip& clip);
+
+
+ bool grabState();
+ bool grabClip();
+
+ GrTAllocator<Draw> fDraws;
+ // HACK: We hold refs on textures in saved state but not RTs, VBs, and IBs.
+ // a) RTs aren't ref counted (yet)
+ // b) we are only using this class for text which doesn't use VBs or IBs
+ // This should be fixed by either refcounting them all or having some
+ // notification occur if a cache is purging an object we have a ptr to.
+ GrTAllocator<SavedDrawState> fStates;
+
+ GrTAllocator<GrClip> fClips;
+ bool fClipChanged;
+
+ // vertices are either queued in cpu arrays or some vertex buffer pool
+ // that knows about a specific GrGpu object.
+ GrAllocPool fCPUVertices;
+ GrVertexBufferAllocPool* fBufferVertices;
+ GrAllocPool fIndices;
+ void* fCurrReservedVertices;
+ void* fCurrReservedIndices;
+ // valid if we're queueing vertices in fBufferVertices
+ GrVertexBuffer* fCurrVertexBuffer;
+ uint32_t fCurrStartVertex;
+
+ // caller may conservatively over allocate vertices / indices.
+ // we release unused space back to allocator if possible
+ size_t fReservedVertexBytes;
+ size_t fReservedIndexBytes;
+ size_t fUsedReservedVertexBytes;
+ size_t fUsedReservedIndexBytes;
+
+ static const uint32_t STATES_BLOCK_SIZE = 8;
+ static const uint32_t DRAWS_BLOCK_SIZE = 8;
+ static const uint32_t CLIPS_BLOCK_SIZE = 8;
+ static const uint32_t VERTEX_BLOCK_SIZE = 1 << 12;
+ static const uint32_t INDEX_BLOCK_SIZE = 1 << 10;
+ int8_t fDrawsStorage[sizeof(Draw) *
+ DRAWS_BLOCK_SIZE];
+ int8_t fStatesStorage[sizeof(SavedDrawState) *
+ STATES_BLOCK_SIZE];
+ int8_t fClipsStorage[sizeof(GrClip) *
+ CLIPS_BLOCK_SIZE];
+};
+
+#endif
diff --git a/gpu/include/GrIndexBuffer.h b/gpu/include/GrIndexBuffer.h
new file mode 100644
index 0000000000..0f4c4d691f
--- /dev/null
+++ b/gpu/include/GrIndexBuffer.h
@@ -0,0 +1,92 @@
+/*
+ Copyright 2010 Google Inc.
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ */
+
+
+#ifndef GrIndexBuffer_DEFINED
+#define GrIndexBuffer_DEFINED
+
+#include "GrRefCnt.h"
+
+class GrIndexBuffer : public GrRefCnt {
+protected:
+ GrIndexBuffer(uint32_t sizeInBytes, bool dynamic) :
+ fSizeInBytes(sizeInBytes),
+ fDynamic(dynamic) {}
+public:
+ virtual ~GrIndexBuffer() {}
+
+ /**
+ Retrieves the size of the index buffer
+
+ @return the size of the index buffer in bytes
+ */
+ uint32_t size() const { return fSizeInBytes; }
+
+ /**
+ Retrieves whether the index buffer was created with the dynamic flag
+
+ @return true if the index buffer was created with the dynamic flag
+ */
+ bool dynamic() const { return fDynamic; }
+
+ /**
+ Indicates that GPU context in which this veretx buffer was created is
+ destroyed and that Ganesh should not attempt to free the texture with the
+ underlying API.
+ */
+ virtual void abandon() = 0;
+
+ /**
+ Locks the index buffer to be written by the CPU.
+
+ The previous content of the index buffer is invalidated. It is an error to
+ draw whil the buffer is locked. It is an error to call lock on an already
+ locked index buffer.
+
+ @return a pointer to the index data or NULL if the lock fails.
+ */
+ virtual void* lock() = 0;
+
+ /**
+ Unlocks the index buffer.
+
+ The pointer returned by the previous lock call will no longer be valid.
+ */
+ virtual void unlock() = 0;
+
+ /**
+ Queries whether the index buffer has been locked.
+
+ @return true if the index buffer is locked, false otherwise.
+ */
+ virtual bool isLocked() const = 0;
+
+ /**
+ Updates the index buffer data.
+
+ The size of the index buffer will be preserved. However, only the updated
+ region will have defined contents.
+
+ @return returns true if the update succeeds, false otherwise.
+ */
+ virtual bool updateData(const void* src, uint32_t srcSizeInBytes) = 0;
+
+private:
+ uint32_t fSizeInBytes;
+ bool fDynamic;
+};
+
+#endif
diff --git a/gpu/include/GrInstanceCounter.h b/gpu/include/GrInstanceCounter.h
new file mode 100644
index 0000000000..11cec2b2ec
--- /dev/null
+++ b/gpu/include/GrInstanceCounter.h
@@ -0,0 +1,47 @@
+/*
+ Copyright 2010 Google Inc.
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ */
+
+
+#ifndef GrInstanceCounter_DEFINED
+#define GrInstanceCounter_DEFINED
+
+#include "GrTypes.h"
+
+template <typename T> class GrInstanceCounter {
+public:
+ GrInstanceCounter() {
+ ++gCounter;
+ GrPrintf("+ %s %d\n", T::InstanceCounterClassName(), gCounter);
+ }
+
+ ~GrInstanceCounter() {
+ --gCounter;
+ GrPrintf("- %s %d\n", T::InstanceCounterClassName(), gCounter);
+ }
+
+private:
+ static int gCounter;
+};
+
+template <typename T> int GrInstanceCounter<T>::gCounter;
+
+#define DECLARE_INSTANCE_COUNTER(T) \
+ static const char* InstanceCounterClassName() { return #T; } \
+ friend class GrInstanceCounter<T>; \
+ GrInstanceCounter<T> fInstanceCounter
+
+#endif
+
diff --git a/gpu/include/GrKey.h b/gpu/include/GrKey.h
new file mode 100644
index 0000000000..19133aee7a
--- /dev/null
+++ b/gpu/include/GrKey.h
@@ -0,0 +1,47 @@
+/*
+ Copyright 2010 Google Inc.
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ */
+
+
+#ifndef GrKey_DEFINED
+#define GrKey_DEFINED
+
+#include "GrRefCnt.h"
+
+class GrKey : public GrRefCnt {
+public:
+ typedef intptr_t Hash;
+
+ explicit GrKey(Hash hash) : fHash(hash) {}
+
+ intptr_t getHash() const { return fHash; }
+
+ bool operator<(const GrKey& rh) const {
+ return fHash < rh.fHash || (fHash == rh.fHash && this->lt(rh));
+ }
+ bool operator==(const GrKey& rh) const {
+ return fHash == rh.fHash && this->eq(rh);
+ }
+
+protected:
+ virtual bool lt(const GrKey& rh) const = 0;
+ virtual bool eq(const GrKey& rh) const = 0;
+
+private:
+ const Hash fHash;
+};
+
+#endif
+
diff --git a/gpu/include/GrMatrix.h b/gpu/include/GrMatrix.h
new file mode 100644
index 0000000000..43fd4a5ed1
--- /dev/null
+++ b/gpu/include/GrMatrix.h
@@ -0,0 +1,370 @@
+/*
+ Copyright 2010 Google Inc.
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ */
+
+
+#ifndef GrMatrix_DEFINED
+#define GrMatrix_DEFINED
+
+#include "GrPoint.h"
+
+struct GrRect;
+
+/*
+ * 3x3 matrix
+ */
+class GrMatrix {
+public:
+ static const GrMatrix& I();
+ static const GrScalar gRESCALE;
+ /**
+ * Handy index constants
+ */
+ enum {
+ kScaleX,
+ kSkewX,
+ kTransX,
+ kSkewY,
+ kScaleY,
+ kTransY,
+ kPersp0,
+ kPersp1,
+ kPersp2
+ };
+
+ /**
+ * Create an uninitialized matrix
+ */
+ GrMatrix() {
+ fTypeMask = 0;
+ }
+
+ /**
+ * Create a matrix from an array of values
+ * @param values row-major array of matrix components
+ */
+ explicit GrMatrix(GrScalar* values) {
+ setToArray(values);
+ }
+
+ /**
+ * Create a matrix from values
+ * @param scaleX (0,0) matrix element
+ * @param skewX (0,1) matrix element
+ * @param transX (0,2) matrix element
+ * @param skewY (1,0) matrix element
+ * @param scaleY (1,1) matrix element
+ * @param transY (1,2) matrix element
+ * @param persp0 (2,0) matrix element
+ * @param persp1 (2,1) matrix element
+ * @param persp2 (2,2) matrix element
+ */
+ GrMatrix(GrScalar scaleX,
+ GrScalar skewX,
+ GrScalar transX,
+ GrScalar skewY,
+ GrScalar scaleY,
+ GrScalar transY,
+ GrScalar persp0,
+ GrScalar persp1,
+ GrScalar persp2) {
+ setAll(scaleX, skewX, transX,
+ skewY, scaleY, transY,
+ persp0, persp1, persp2);
+ }
+
+ /**
+ * access matrix component
+ * @return matrix component value
+ */
+ const GrScalar& operator[] (int idx) const {
+ GrAssert((unsigned)idx < 9);
+ return fM[idx];
+ }
+
+ /**
+ * Set a matrix from an array of values
+ * @param values row-major array of matrix components
+ */
+ void setToArray(GrScalar* values) {
+ for (int i = 0; i < 9; ++i) {
+ fM[i] = values[i];
+ }
+ setTypeMask();
+ }
+
+ /**
+ * Create a matrix from values
+ * @param scaleX (0,0) matrix element
+ * @param skewX (0,1) matrix element
+ * @param transX (0,2) matrix element
+ * @param skewY (1,0) matrix element
+ * @param scaleY (1,1) matrix element
+ * @param transY (1,2) matrix element
+ * @param persp0 (2,0) matrix element
+ * @param persp1 (2,1) matrix element
+ * @param persp2 (2,2) matrix element
+ */
+ void setAll(GrScalar scaleX,
+ GrScalar skewX,
+ GrScalar transX,
+ GrScalar skewY,
+ GrScalar scaleY,
+ GrScalar transY,
+ GrScalar persp0,
+ GrScalar persp1,
+ GrScalar persp2) {
+ fM[kScaleX] = scaleX;
+ fM[kSkewX] = skewX;
+ fM[kTransX] = transX;
+ fM[kSkewY] = skewY;
+ fM[kScaleY] = scaleY;
+ fM[kTransY] = transY;
+ fM[kPersp0] = persp0;
+ fM[kPersp1] = persp1;
+ fM[kPersp2] = persp2;
+
+ setTypeMask();
+ }
+
+ /**
+ * set matrix component
+ * @param idx index of component to set
+ * @param value value to set component to
+ */
+ inline void set(int idx, GrScalar value);
+
+ /**
+ * make this matrix an identity matrix
+ */
+ void setIdentity();
+
+ /**
+ * overwrite entire matrix to be a translation matrix
+ * @param dx amount to translate by in x
+ * @param dy amount to translate by in y
+ */
+ void setTranslate(GrScalar dx, GrScalar dy);
+
+ /**
+ * overwrite entire matrix to be a scaling matrix
+ * @param sx x scale factor
+ * @param sy y scale factor
+ */
+ void setScale(GrScalar sx, GrScalar sy);
+
+ /**
+ * overwrite entire matrix to be a skew matrix
+ * @param skx x skew factor
+ * @param sky y skew factor
+ */
+ void setSkew(GrScalar skx, GrScalar sky);
+
+ /**
+ * set this matrix to be a concantenation of two
+ * matrices (a*b). Either a, b, or both can be this matrix.
+ * @param a first matrix to multiply
+ * @param b second matrix to multiply
+ */
+ void setConcat(const GrMatrix& a, const GrMatrix& b);
+
+ /**
+ * Set this matrix to this*m
+ * @param m matrix to concatenate
+ */
+ void preConcat(const GrMatrix& m);
+
+ /**
+ * Set this matrix to m*this
+ * @param m matrix to concatenate
+ */
+ void postConcat(const GrMatrix& m);
+
+ /**
+ * Compute the inverse of this matrix, and return true if it is invertible,
+ * or false if not.
+ *
+ * If inverted is not null, and the matrix is invertible, then the inverse
+ * is written into it. If the matrix is not invertible (this method returns
+ * false) then inverted is left unchanged.
+ */
+ bool invert(GrMatrix* inverted) const;
+
+ /**
+ * Transforms a point by the matrix
+ *
+ * @param src the point to transform
+ * @return the transformed point
+ */
+ GrPoint mapPoint(const GrPoint& src) const {
+ GrPoint result;
+ (this->*gMapProcs[fTypeMask])(&result, &src, 1);
+ return result;
+ }
+
+ /**
+ * Transforms an array of points by the matrix.
+ *
+ * @param dstPts the array to write transformed points into
+ * @param srcPts the array of points to transform
+ @ @param count the number of points to transform
+ */
+ void mapPoints(GrPoint dstPts[],
+ const GrPoint srcPts[],
+ uint32_t count) const {
+ (this->*gMapProcs[fTypeMask])(dstPts, srcPts, count);
+ }
+
+ /**
+ * Transforms pts with arbitrary stride in place.
+ *
+ * @param start pointer to first point to transform
+ * @param stride distance in bytes between consecutive points
+ @ @param count the number of points to transform
+ */
+ void mapPointsWithStride(GrPoint* start,
+ size_t stride,
+ uint32_t count) const {
+ for (uint32_t i = 0; i < count; ++i) {
+ this->mapPoints(start, start, 1);
+ start = (GrPoint*)((intptr_t)start + stride);
+ }
+ }
+
+ /**
+ * Transform the 4 corners of the src rect, and return the bounding rect
+ * in the dst rect. Note: src and dst may point to the same memory.
+ */
+ void mapRect(GrRect* dst, const GrRect& src) const;
+
+ /**
+ * Transform the 4 corners of the rect, and return their bounds in the rect
+ */
+ void mapRect(GrRect* rect) const {
+ this->mapRect(rect, *rect);
+ }
+
+ /**
+ * Checks if matrix is a perspective matrix.
+ * @return true if third row is not (0, 0, 1)
+ */
+ bool hasPerspective() const;
+
+ /**
+ * Checks whether matrix is identity
+ * @return true if matrix is idenity
+ */
+ bool isIdentity() const;
+
+ /**
+ * Calculates the maximum stretching factor of the matrix. Only defined if
+ * the matrix does not have perspective.
+ *
+ * @return maximum strecthing factor or negative if matrix has perspective.
+ */
+ GrScalar getMaxStretch() const;
+
+ /**
+ * Checks for matrix equality. Test is element-by-element equality,
+ * not a homogeneous test.
+ * @return true if matrices are equal, false otherwise
+ */
+ bool operator == (const GrMatrix& m) const;
+
+ /**
+ * Checks for matrix inequality. Test is element-by-element inequality,
+ * not a homogeneous test.
+ * @return true if matrices are not equal, false otherwise
+ */
+ bool operator != (const GrMatrix& m) const;
+
+ static void UnitTest();
+
+private:
+
+ void setTypeMask();
+
+ double determinant() const;
+
+ enum TypeBits {
+ kScale_TypeBit = 1 << 0, // set if scales are not both 1
+ kTranslate_TypeBit = 1 << 1, // set if translates are not both 0
+ kSkew_TypeBit = 1 << 2, // set if skews are not both 0
+ kPerspective_TypeBit = 1 << 3, // set if perspective
+ kZeroScale_TypeBit = 1 << 4, // set if scales are both zero
+ };
+
+ void mapIdentity(GrPoint* dst, const GrPoint* src, uint32_t count) const;
+ void mapScale(GrPoint* dst, const GrPoint* src, uint32_t count) const;
+ void mapTranslate(GrPoint* dst, const GrPoint* src, uint32_t count) const;
+ void mapScaleAndTranslate(GrPoint* dst, const GrPoint* src, uint32_t count) const;
+ void mapSkew(GrPoint* dst, const GrPoint* src, uint32_t count) const;
+ void mapScaleAndSkew(GrPoint* dst, const GrPoint* src, uint32_t count) const;
+ void mapSkewAndTranslate(GrPoint* dst, const GrPoint* src, uint32_t count) const;
+ void mapNonPerspective(GrPoint* dst, const GrPoint* src, uint32_t count) const;
+ void mapPerspective(GrPoint* dst, const GrPoint* src, uint32_t count) const;
+ void mapZero(GrPoint* dst, const GrPoint* src, uint32_t count) const;
+ void mapSetToTranslate(GrPoint* dst, const GrPoint* src, uint32_t count) const;
+ void mapSwappedScale(GrPoint* dst, const GrPoint* src, uint32_t count) const;
+ void mapSwappedScaleAndTranslate(GrPoint* dst, const GrPoint* src, uint32_t count) const;
+
+ void mapInvalid(GrPoint* dst, const GrPoint* src, uint32_t count) const;
+
+ typedef void (GrMatrix::*MapProc) (GrPoint* dst, const GrPoint* src, uint32_t count) const;
+ static const MapProc gMapProcs[];
+
+ int fTypeMask;
+
+ GrScalar fM[9];
+};
+
+void GrMatrix::set(int idx, GrScalar value) {
+ GrAssert((unsigned)idx < 9);
+ fM[idx] = value;
+ if (idx > 5) {
+ if (0 != fM[kPersp0] || 0 != fM[kPersp1] ||
+ gRESCALE != fM[kPersp2]) {
+ fTypeMask |= kPerspective_TypeBit;
+ } else {
+ fTypeMask &= ~kPerspective_TypeBit;
+ }
+ } else if (!(idx % 4)) {
+ if ((GR_Scalar1 == fM[kScaleX] && GR_Scalar1 == fM[kScaleY])) {
+ fTypeMask &= ~kScale_TypeBit;
+ fTypeMask &= ~kZeroScale_TypeBit;
+ } else {
+ fTypeMask |= kScale_TypeBit;
+ if ((0 == fM[kScaleX] && 0 == fM[kScaleY])) {
+ fTypeMask |= kZeroScale_TypeBit;
+ } else {
+ fTypeMask &= ~kZeroScale_TypeBit;
+ }
+ }
+ } else if (2 == (idx % 3)) {
+ if (0 != fM[kTransX] || 0 != fM[kTransY]) {
+ fTypeMask |= kTranslate_TypeBit;
+ } else {
+ fTypeMask &= ~kTranslate_TypeBit;
+ }
+ } else {
+ if (0 != fM[kSkewX] || 0 != fM[kSkewY]) {
+ fTypeMask |= kSkew_TypeBit;
+ } else {
+ fTypeMask &= ~kSkew_TypeBit;
+ }
+ }
+}
+
+#endif
diff --git a/gpu/include/GrMemory.h b/gpu/include/GrMemory.h
new file mode 100644
index 0000000000..673d0ab43d
--- /dev/null
+++ b/gpu/include/GrMemory.h
@@ -0,0 +1,151 @@
+/*
+ Copyright 2010 Google Inc.
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ */
+
+
+#ifndef GrMemory_DEFINED
+#define GrMemory_DEFINED
+
+#include "GrNoncopyable.h"
+
+class GrAutoMalloc : GrNoncopyable {
+public:
+ GrAutoMalloc(size_t bytes) : fPtr(GrMalloc(bytes)) {}
+ ~GrAutoMalloc() { GrFree(fPtr); }
+
+ /**
+ * Return the allocated memory, or NULL if it has already been freed or
+ * detached.
+ */
+ void* get() const { return fPtr; }
+
+ /**
+ * transfer ownership of the memory to the caller. It must be freed with
+ * a call to GrFree()
+ */
+ void* detach() {
+ void* ptr = fPtr;
+ fPtr = NULL; // we no longer own the block
+ return ptr;
+ }
+
+ /**
+ * free the block now. get() will now return NULL
+ */
+ void free() {
+ GrFree(fPtr);
+ fPtr = NULL;
+ }
+
+private:
+ void* fPtr;
+};
+
+/**
+ * Variant of GrAutoMalloc with a compile-time specified byte size that is
+ * pre-allocated in the class object, avoiding a call to to GrMalloc if
+ * possible.
+ */
+template <size_t SIZE> class GrAutoSMalloc : GrNoncopyable {
+public:
+ GrAutoSMalloc() {
+ fPtr = fStorage;
+ fAllocatedBytes = SIZE;
+ }
+
+ explicit GrAutoSMalloc(size_t bytes) {
+ if (bytes > SIZE) {
+ fPtr = GrMalloc(bytes);
+ fAllocatedBytes = bytes;
+ } else {
+ fPtr = fStorage;
+ fAllocatedBytes = SIZE;
+ }
+ }
+
+ ~GrAutoSMalloc() {
+ if (fPtr != (void*)fStorage) {
+ GrFree(fPtr);
+ }
+ }
+
+ /**
+ * Return the allocated memory, or NULL if it has already been freed or
+ * detached.
+ */
+ void* get() const { return fPtr; }
+
+ /**
+ * Reallocates to a new size. May or may not call malloc. The contents
+ * are not preserved. If growOnly is true it will never reduce the
+ * allocated size.
+ */
+ void* realloc(size_t newSize, bool growOnly = false) {
+ if (newSize <= SIZE) {
+ if (NULL == fPtr) {
+ fPtr = fStorage;
+ fAllocatedBytes = SIZE;
+ } else if (!growOnly && fPtr != (void*)fStorage) {
+ GrFree(fPtr);
+ fPtr = fStorage;
+ fAllocatedBytes = SIZE;
+ }
+ } else if ((newSize > fAllocatedBytes) ||
+ (!growOnly && newSize < (fAllocatedBytes >> 1))) {
+ if (NULL != fPtr && fPtr != (void*)fStorage) {
+ GrFree(fPtr);
+ }
+ fPtr = GrMalloc(newSize);
+ fAllocatedBytes = newSize;
+ }
+ GrAssert(fAllocatedBytes >= newSize);
+ GrAssert((fPtr == fStorage) == (fAllocatedBytes == SIZE));
+ GR_DEBUGCODE(memset(fPtr, 0xEF, fAllocatedBytes));
+ return fPtr;
+ }
+
+ /**
+ * free the block now. get() will now return NULL
+ */
+ void free() {
+ if (fPtr != (void*)fStorage) {
+ GrFree(fPtr);
+ }
+ fAllocatedBytes = 0;
+ fPtr = NULL;
+ }
+
+private:
+ void* fPtr;
+ uint32_t fAllocatedBytes;
+ uint32_t fStorage[GrALIGN4(SIZE) >> 2];
+};
+
+/**
+ * Variant of GrAutoMalloc with a compile-time specified byte size that is
+ * pre-allocated in the class object, avoiding a call to to GrMalloc if
+ * possible.
+ */
+template <int COUNT, typename T>
+class GrAutoSTMalloc : public GrAutoSMalloc<COUNT * sizeof(T)> {
+public:
+ GrAutoSTMalloc(int count) : GrAutoSMalloc<COUNT * sizeof(T)>(count * sizeof(T)) {}
+
+ operator T*() { return (T*)this->get(); }
+};
+
+
+#endif
+
diff --git a/gpu/include/GrMesh.h b/gpu/include/GrMesh.h
new file mode 100644
index 0000000000..4d904e41bd
--- /dev/null
+++ b/gpu/include/GrMesh.h
@@ -0,0 +1,42 @@
+#ifndef GrMesh_DEFINED
+#define GrMesh_DEFINED
+
+#include "SkRect.h"
+#include "SkPoint.h"
+
+class SkCanvas;
+class SkPaint;
+
+class GrMesh {
+public:
+ GrMesh();
+ ~GrMesh();
+
+ GrMesh& operator=(const GrMesh& src);
+
+ void init(const SkRect& bounds, int rows, int cols,
+ const SkRect& texture);
+
+ const SkRect& bounds() const { return fBounds; }
+
+ int rows() const { return fRows; }
+ int cols() const { return fCols; }
+ SkPoint& pt(int row, int col) {
+ return fPts[row * (fRows + 1) + col];
+ }
+
+ void draw(SkCanvas*, const SkPaint&);
+ void drawWireframe(SkCanvas* canvas, const SkPaint& paint);
+
+private:
+ SkRect fBounds;
+ int fRows, fCols;
+ SkPoint* fPts;
+ SkPoint* fTex; // just points into fPts, not separately allocated
+ int fCount;
+ uint16_t* fIndices;
+ int fIndexCount;
+};
+
+#endif
+
diff --git a/gpu/include/GrNoncopyable.h b/gpu/include/GrNoncopyable.h
new file mode 100644
index 0000000000..888e3b173b
--- /dev/null
+++ b/gpu/include/GrNoncopyable.h
@@ -0,0 +1,38 @@
+/*
+ Copyright 2010 Google Inc.
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ */
+
+
+#ifndef GrNoncopyable_DEFINED
+#define GrNoncopyable_DEFINED
+
+#include "GrTypes.h"
+
+/**
+ * Base for classes that want to disallow copying themselves. It makes its
+ * copy-constructor and assignment operators private (and unimplemented).
+ */
+class GrNoncopyable {
+public:
+ GrNoncopyable() {}
+
+private:
+ // illegal
+ GrNoncopyable(const GrNoncopyable&);
+ GrNoncopyable& operator=(const GrNoncopyable&);
+};
+
+#endif
+
diff --git a/gpu/include/GrPath.h b/gpu/include/GrPath.h
new file mode 100644
index 0000000000..a9b75665c3
--- /dev/null
+++ b/gpu/include/GrPath.h
@@ -0,0 +1,84 @@
+/*
+ Copyright 2010 Google Inc.
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ */
+
+
+#ifndef GrPath_DEFINED
+#define GrPath_DEFINED
+
+#include "GrPathSink.h"
+#include "GrPathIter.h"
+#include "GrTDArray.h"
+#include "GrPoint.h"
+
+class GrPath : public GrPathSink {
+public:
+ GrPath();
+ GrPath(const GrPath&);
+ explicit GrPath(GrPathIter&);
+ virtual ~GrPath();
+
+ GrPathIter::ConvexHint getConvexHint() const { return fConvexHint; }
+ void setConvexHint(GrPathIter::ConvexHint hint) { fConvexHint = hint; }
+
+ void resetFromIter(GrPathIter*);
+
+ // overrides from GrPathSink
+
+ virtual void moveTo(GrScalar x, GrScalar y);
+ virtual void lineTo(GrScalar x, GrScalar y);
+ virtual void quadTo(GrScalar x0, GrScalar y0, GrScalar x1, GrScalar y1);
+ virtual void cubicTo(GrScalar x0, GrScalar y0, GrScalar x1, GrScalar y1,
+ GrScalar x2, GrScalar y2);
+ virtual void close();
+
+ class Iter : public GrPathIter {
+ public:
+ Iter(const GrPath& path);
+
+ // overrides from GrPathIter
+ virtual Command next(GrPoint points[]);
+ virtual ConvexHint hint() const;
+ virtual Command next();
+ virtual void rewind();
+ private:
+ const GrPath& fPath;
+ GrPoint fLastPt;
+ int fVerbIndex;
+ int fPtIndex;
+ };
+
+private:
+ enum Verb {
+ kMove, kLine, kQuad, kCubic, kClose
+ };
+
+ GrTDArray<uint8_t> fVerbs;
+ GrTDArray<GrPoint> fPts;
+ GrPathIter::ConvexHint fConvexHint;
+
+ // this ensures we have a moveTo at the start of each contour
+ inline void ensureMoveTo();
+
+ bool wasLastVerb(Verb verb) const {
+ int count = fVerbs.count();
+ return count > 0 && verb == fVerbs[count - 1];
+ }
+
+ friend class Iter;
+};
+
+#endif
+
diff --git a/gpu/include/GrPathIter.h b/gpu/include/GrPathIter.h
new file mode 100644
index 0000000000..028faaa14d
--- /dev/null
+++ b/gpu/include/GrPathIter.h
@@ -0,0 +1,110 @@
+/*
+ Copyright 2010 Google Inc.
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ */
+
+
+#ifndef GrPathIter_DEFINED
+#define GrPathIter_DEFINED
+
+#include "GrTypes.h"
+
+struct GrPoint;
+
+/**
+ 2D Path iterator. Porting layer creates a subclass of this. It allows Ganesh to
+ parse the top-level API's 2D paths. Supports lines, quadratics, and cubic
+ pieces and moves (multi-part paths).
+ */
+class GrPathIter {
+public:
+ /**
+ Returned by next(). Indicates the next piece of the path.
+ */
+ enum Command {
+ kMove_Command, //!< next() returns 1 pt
+ // Starts a new subpath at
+ // at the returned point
+ kLine_Command, //!< next() returns 2 pts
+ // Adds a line segment
+ kQuadratic_Command, //!< next() returns 3 pts
+ // Adds a quadratic segment
+ kCubic_Command, //!< next() returns 4 pts
+ // Adds a cubic segment
+ kClose_Command, //!< next() returns 0 pts
+ kEnd_Command //!< next() returns 0 pts
+ // Implictly closes the last
+ // point
+ };
+
+ enum ConvexHint {
+ kNone_ConvexHint, //<! No hint about convexity
+ // of the path
+ kConvex_ConvexHint, //<! Path is one convex piece
+ kNonOverlappingConvexPieces_ConvexHint, //<! Multiple convex pieces,
+ // pieces are known to be
+ // disjoint
+ kSameWindingConvexPieces_ConvexHint, //<! Multiple convex pieces,
+ // may or may not intersect,
+ // either all wind cw or all
+ // wind ccw.
+ kConcave_ConvexHint //<! Path is known to be
+ // concave
+ };
+
+ static int NumCommandPoints(Command cmd) {
+ static const int numPoints[] = {
+ 1, 2, 3, 4, 0, 0
+ };
+ return numPoints[cmd];
+ }
+
+ virtual ~GrPathIter() {};
+
+ /**
+ Iterates through the path. Should not be called after
+ kEnd_Command has been returned once. This version retrieves the
+ points for the command.
+ @param points The points relevant to returned commend. See Command
+ enum for number of points valid for each command.
+ @return The next command of the path.
+ */
+ virtual Command next(GrPoint points[4]) = 0;
+
+ /**
+ * If the host API has knowledge of the convexity of the path
+ * it can be communicated by this hint. Ganesh can make these
+ * determinations itself. So it is not necessary to compute
+ * convexity status if it isn't already determined.
+ *
+ * @return a hint about the convexity of the path.
+ */
+ virtual ConvexHint hint() const { return kNone_ConvexHint; }
+
+ /**
+ Iterates through the path. Should not be called after
+ kEnd_Command has been returned once. This version does not retrieve the
+ points for the command.
+ @return The next command of the path.
+ */
+ virtual Command next() = 0;
+
+ /**
+ Restarts iteration from the beginning.
+ */
+ virtual void rewind() = 0;
+
+};
+
+#endif
diff --git a/gpu/include/GrPathSink.h b/gpu/include/GrPathSink.h
new file mode 100644
index 0000000000..4e8a0c2c43
--- /dev/null
+++ b/gpu/include/GrPathSink.h
@@ -0,0 +1,36 @@
+/*
+ Copyright 2010 Google Inc.
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ */
+
+
+#ifndef GrPathSink_DEFINED
+#define GrPathSink_DEFINED
+
+#include "GrScalar.h"
+
+class GrPathSink {
+public:
+ virtual ~GrPathSink() {}
+
+ virtual void moveTo(GrScalar x, GrScalar y) = 0;
+ virtual void lineTo(GrScalar x, GrScalar y) = 0;
+ virtual void quadTo(GrScalar x0, GrScalar y0, GrScalar x1, GrScalar y1) = 0;
+ virtual void cubicTo(GrScalar x0, GrScalar y0, GrScalar x1, GrScalar y1,
+ GrScalar x2, GrScalar y2) = 0;
+ virtual void close() = 0;
+};
+
+#endif
+
diff --git a/gpu/include/GrPlotMgr.h b/gpu/include/GrPlotMgr.h
new file mode 100644
index 0000000000..cd60bdebde
--- /dev/null
+++ b/gpu/include/GrPlotMgr.h
@@ -0,0 +1,84 @@
+/*
+ Copyright 2010 Google Inc.
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ */
+
+
+#ifndef GrPlotMgr_DEFINED
+#define GrPlotMgr_DEFINED
+
+#include "GrTypes.h"
+#include "GrPoint.h"
+
+class GrPlotMgr : GrNoncopyable {
+public:
+ GrPlotMgr(int width, int height) {
+ fDim.set(width, height);
+ size_t needed = width * height;
+ if (needed <= sizeof(fStorage)) {
+ fBusy = fStorage;
+ } else {
+ fBusy = new char[needed];
+ }
+ this->reset();
+ }
+
+ ~GrPlotMgr() {
+ if (fBusy != fStorage) {
+ delete[] fBusy;
+ }
+ }
+
+ void reset() {
+ Gr_bzero(fBusy, fDim.fX * fDim.fY);
+ }
+
+ bool newPlot(GrIPoint16* loc) {
+ char* busy = fBusy;
+ for (int y = 0; y < fDim.fY; y++) {
+ for (int x = 0; x < fDim.fX; x++) {
+ if (!*busy) {
+ *busy = true;
+ loc->set(x, y);
+ return true;
+ }
+ busy++;
+ }
+ }
+ return false;
+ }
+
+ bool isBusy(int x, int y) const {
+ GrAssert((unsigned)x < (unsigned)fDim.fX);
+ GrAssert((unsigned)y < (unsigned)fDim.fY);
+ return fBusy[y * fDim.fX + x] != 0;
+ }
+
+ void freePlot(int x, int y) {
+ GrAssert((unsigned)x < (unsigned)fDim.fX);
+ GrAssert((unsigned)y < (unsigned)fDim.fY);
+ fBusy[y * fDim.fX + x] = false;
+ }
+
+private:
+ enum {
+ STORAGE = 64
+ };
+ char fStorage[STORAGE];
+ char* fBusy;
+ GrIPoint16 fDim;
+};
+
+#endif
+
diff --git a/gpu/include/GrPoint.h b/gpu/include/GrPoint.h
new file mode 100644
index 0000000000..bb24959c34
--- /dev/null
+++ b/gpu/include/GrPoint.h
@@ -0,0 +1,287 @@
+/*
+ Copyright 2010 Google Inc.
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ */
+
+
+#ifndef GrPoint_DEFINED
+#define GrPoint_DEFINED
+
+#include "GrTypes.h"
+#include "GrScalar.h"
+
+/**
+ * 2D Point struct
+ */
+struct GrPoint {
+public:
+ GrScalar fX, fY;
+
+ GrPoint() {}
+ GrPoint(GrScalar x, GrScalar y) { fX = x; fY = y; }
+
+ GrScalar x() const { return fX; }
+ GrScalar y() const { return fY; }
+
+ void set(GrScalar x, GrScalar y) {
+ fX = x;
+ fY = y;
+ }
+
+ void setAsMidPoint(const GrPoint& a, const GrPoint& b) {
+ fX = GrScalarAve(a.fX, b.fX);
+ fY = GrScalarAve(a.fY, b.fY);
+ }
+
+ void offset(GrScalar dx, GrScalar dy) {
+ fX += dx;
+ fY += dy;
+ }
+
+ GrScalar distanceToSqd(const GrPoint& p) const {
+ GrScalar dx = (p.fX - fX);
+ GrScalar dy = (p.fY - fY);
+ return GrMul(dx, dx) + GrMul(dy, dy);
+ }
+
+ GrScalar distanceTo(const GrPoint& p) const {
+ // TODO: fixed point sqrt
+ return GrFloatToScalar(sqrtf(GrScalarToFloat(distanceToSqd(p))));
+ }
+
+ GrScalar distanceToOriginSqd() const {
+ return GrMul(fX, fX) + GrMul(fY, fY);
+ }
+
+ GrScalar distanceToOrigin() const {
+ return GrFloatToScalar(sqrtf(GrScalarToFloat(distanceToOriginSqd())));
+ }
+
+ inline GrScalar distanceToLineBetweenSqd(const GrPoint& a,
+ const GrPoint& b) const;
+
+ inline GrScalar distanceToLineBetween(const GrPoint& a,
+ const GrPoint& b) const;
+
+ inline GrScalar distanceToLineSegmentBetweenSqd(const GrPoint& a,
+ const GrPoint& b) const;
+
+ inline GrScalar distanceToLineSegmentBetween(const GrPoint& a,
+ const GrPoint& b) const;
+
+ // counter-clockwise fan
+ void setRectFan(GrScalar l, GrScalar t, GrScalar r, GrScalar b) {
+ GrPoint* v = this;
+ v[0].set(l, t);
+ v[1].set(l, b);
+ v[2].set(r, b);
+ v[3].set(r, t);
+ }
+
+ void setRectFan(GrScalar l, GrScalar t, GrScalar r, GrScalar b, size_t stride) {
+ GrAssert(stride >= sizeof(GrPoint));
+ ((GrPoint*)((intptr_t)this + 0 * stride))->set(l, t);
+ ((GrPoint*)((intptr_t)this + 1 * stride))->set(l, b);
+ ((GrPoint*)((intptr_t)this + 2 * stride))->set(r, b);
+ ((GrPoint*)((intptr_t)this + 3 * stride))->set(r, t);
+ }
+
+ // counter-clockwise fan
+ void setIRectFan(int l, int t, int r, int b) {
+ GrPoint* v = this;
+ v[0].set(GrIntToScalar(l), GrIntToScalar(t));
+ v[1].set(GrIntToScalar(l), GrIntToScalar(b));
+ v[2].set(GrIntToScalar(r), GrIntToScalar(b));
+ v[3].set(GrIntToScalar(r), GrIntToScalar(t));
+ }
+
+ void setIRectFan(int l, int t, int r, int b, size_t stride) {
+ GrAssert(stride >= sizeof(GrPoint));
+ ((GrPoint*)((intptr_t)this + 0 * stride))->set(GrIntToScalar(l),
+ GrIntToScalar(t));
+ ((GrPoint*)((intptr_t)this + 1 * stride))->set(GrIntToScalar(l),
+ GrIntToScalar(b));
+ ((GrPoint*)((intptr_t)this + 2 * stride))->set(GrIntToScalar(r),
+ GrIntToScalar(b));
+ ((GrPoint*)((intptr_t)this + 3 * stride))->set(GrIntToScalar(r),
+ GrIntToScalar(t));
+ }
+
+ bool operator ==(const GrPoint& p) const {
+ return fX == p.fX && fY == p.fY;
+ }
+
+ bool operator !=(const GrPoint& p) const {
+ return fX != p.fX || fY != p.fY;
+ }
+};
+
+struct GrIPoint16 {
+ int16_t fX, fY;
+
+ void set(intptr_t x, intptr_t y) {
+ fX = GrToS16(x);
+ fY = GrToS16(y);
+ }
+};
+
+struct GrVec {
+public:
+ GrScalar fX, fY;
+
+ GrVec() {}
+ GrVec(GrScalar x, GrScalar y) { fX = x; fY = y; }
+
+ GrScalar x() const { return fX; }
+ GrScalar y() const { return fY; }
+
+ /**
+ * set x and y length of the vector.
+ */
+ void set(GrScalar x, GrScalar y) {
+ fX = x;
+ fY = y;
+ }
+
+ /**
+ * set vector to point from a to b.
+ */
+ void setBetween(const GrPoint& a, const GrPoint& b) {
+ fX = b.fX - a.fX;
+ fY = b.fY - a.fY;
+ }
+
+ /**
+ * length of the vector squared.
+ */
+ GrScalar lengthSqd() const {
+ return GrMul(fX, fX) + GrMul(fY, fY);
+ }
+
+ /**
+ * length of the vector.
+ */
+ GrScalar length() const {
+ // TODO: fixed point sqrt
+ return GrFloatToScalar(sqrtf(GrScalarToFloat(lengthSqd())));
+ }
+
+ /**
+ * normalizes the vector if it's length is not 0.
+ * @return true if normalized, otherwise false.
+ */
+ bool normalize() {
+ GrScalar l = lengthSqd();
+ if (l) {
+ // TODO: fixed point sqrt and invert
+ l = 1 / sqrtf(l);
+ fX *= l;
+ fY *= l;
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ * Dot product of this with vec.
+ */
+ GrScalar dot(const GrVec& vec) const {
+ return GrMul(vec.fX, fX) + GrMul(vec.fY, fY);
+ }
+
+ /**
+ * z-value of this cross vec.
+ */
+ GrScalar cross(const GrVec& vec) const {
+ return GrMul(fX, vec.fY) - GrMul(fY, vec.fX);
+ }
+
+ bool operator ==(const GrPoint& p) const {
+ return fX == p.fX && fY == p.fY;
+ }
+
+ bool operator !=(const GrPoint& p) const {
+ return fX != p.fX || fY != p.fY;
+ }
+};
+
+GrScalar GrPoint::distanceToLineBetweenSqd(const GrPoint& a,
+ const GrPoint& b) const {
+ // Let d be the distance between c (this) and line ab.
+ // The area of the triangle defined by a, b, and c is
+ // A = |b-a|*d/2. Let u = b-a and v = c-a. The cross product of
+ // u and v is aligned with the z axis and its magnitude is 2A.
+ // So d = |u x v| / |u|.
+ GrVec u, v;
+ u.setBetween(a,b);
+ v.setBetween(a,*this);
+
+ GrScalar det = u.cross(v);
+ return (GrMul(det, det)) / u.lengthSqd();
+}
+
+GrScalar GrPoint::distanceToLineBetween(const GrPoint& a,
+ const GrPoint& b) const {
+ GrVec u, v;
+ u.setBetween(a,b);
+ v.setBetween(a,*this);
+
+ GrScalar det = u.cross(v);
+ return (GrScalarAbs(det)) / u.length();
+}
+
+GrScalar GrPoint::distanceToLineSegmentBetweenSqd(const GrPoint& a,
+ const GrPoint& b) const {
+ // See comments to distanceToLineBetweenSqd. If the projection of c onto
+ // u is between a and b then this returns the same result as that
+ // function. Otherwise, it returns the distance to the closer of a and
+ // b. Let the projection of v onto u be v'. There are three cases:
+ // 1. v' points opposite to u. c is not between a and b and is closer
+ // to a than b.
+ // 2. v' points along u and has magnitude less than y. c is between
+ // a and b and the distance to the segment is the same as distance
+ // to the line ab.
+ // 3. v' points along u and has greater magnitude than u. c is not
+ // not between a and b and is closer to b than a.
+ // v' = (u dot v) * u / |u|. So if (u dot v)/|u| is less than zero we're
+ // in case 1. If (u dot v)/|u| is > |u| we are in case 3. Otherwise
+ // we're in case 2. We actually compare (u dot v) to 0 and |u|^2 to
+ // avoid a sqrt to compute |u|.
+
+ GrVec u, v;
+ u.setBetween(a,b);
+ v.setBetween(a,*this);
+
+ GrScalar uLengthSqd = u.lengthSqd();
+ GrScalar uDotV = u.dot(v);
+
+ if (uDotV <= 0) {
+ return v.lengthSqd();
+ } else if (uDotV > uLengthSqd) {
+ return b.distanceToSqd(*this);
+ } else {
+ GrScalar det = u.cross(v);
+ return (GrMul(det, det)) / uLengthSqd;
+ }
+}
+
+GrScalar GrPoint::distanceToLineSegmentBetween(const GrPoint& a,
+ const GrPoint& b) const {
+ // TODO: fixed point sqrt
+ return GrFloatToScalar(sqrtf(GrScalarToFloat(distanceToLineSegmentBetweenSqd(a,b))));
+}
+
+
+#endif
+
diff --git a/gpu/include/GrRandom.h b/gpu/include/GrRandom.h
new file mode 100644
index 0000000000..408f61de7b
--- /dev/null
+++ b/gpu/include/GrRandom.h
@@ -0,0 +1,62 @@
+/*
+ Copyright 2010 Google Inc.
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ */
+
+
+#ifndef GrRandom_DEFINED
+#define GrRandom_DEFINED
+
+class GrRandom {
+public:
+ GrRandom() : fSeed(0) {}
+ GrRandom(uint32_t seed) : fSeed(seed) {}
+
+ uint32_t seed() const { return fSeed; }
+
+ uint32_t nextU() {
+ fSeed = fSeed * kMUL + kADD;
+ return fSeed;
+ }
+
+ int32_t nextS() { return (int32_t)this->nextU(); }
+
+ /**
+ * Returns value [0...1) as a float
+ */
+ float nextF() {
+ // const is 1 / (2^32 - 1)
+ return (float)(this->nextU() * 2.32830644e-10);
+ }
+
+ /**
+ * Returns value [min...max) as a float
+ */
+ float nextF(float min, float max) {
+ return min + this->nextF() * (max - min);
+ }
+
+private:
+ /*
+ * These constants taken from "Numerical Recipes in C", reprinted 1999
+ */
+ enum {
+ kMUL = 1664525,
+ kADD = 1013904223
+ };
+ uint32_t fSeed;
+};
+
+#endif
+
diff --git a/gpu/include/GrRect.h b/gpu/include/GrRect.h
new file mode 100644
index 0000000000..5192ebdf18
--- /dev/null
+++ b/gpu/include/GrRect.h
@@ -0,0 +1,284 @@
+/*
+ Copyright 2010 Google Inc.
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ */
+
+
+#ifndef GrRect_DEFINED
+#define GrRect_DEFINED
+
+#include "GrPoint.h"
+
+struct GrIRect {
+ int32_t fLeft, fTop, fRight, fBottom;
+
+ GrIRect() {}
+ GrIRect(int32_t left, int32_t top, int32_t right, int32_t bottom) {
+ fLeft = left;
+ fTop = top;
+ fRight = right;
+ fBottom = bottom;
+ }
+
+ int32_t x() const { return fLeft; }
+ int32_t y() const { return fTop; }
+ int32_t width() const { return fRight - fLeft; }
+ int32_t height() const { return fBottom - fTop; }
+
+ bool isEmpty() const { return fLeft >= fRight || fTop >= fBottom; }
+ bool isInverted() const { return fLeft > fRight || fTop > fBottom; }
+
+ void setEmpty() { fLeft = fTop = fRight = fBottom = 0; }
+
+ void setXYWH(int32_t x, int32_t y, int32_t w, int32_t h) {
+ fLeft = x;
+ fTop = y;
+ fRight = x + w;
+ fBottom = y + h;
+ }
+
+ void setLTRB(int32_t l, int32_t t, int32_t r, int32_t b) {
+ fLeft = l;
+ fTop = t;
+ fRight = r;
+ fBottom = b;
+ }
+
+ /**
+ * Make the largest representable rectangle
+
+ */
+ void setLargest() {
+ fLeft = fTop = GR_Int32Min;
+ fRight = fBottom = GR_Int32Max;
+ }
+
+ bool quickReject(int l, int t, int r, int b) const {
+ return l >= fRight || fLeft >= r || t >= fBottom || fTop >= b;
+ }
+
+ void unionWith(const GrIRect& r) {
+ if (fLeft > r.fLeft) fLeft = r.fLeft;
+ if (fTop > r.fTop) fTop = r.fTop;
+ if (fRight < r.fRight) fRight = r.fRight;
+ if (fBottom < r.fBottom) fBottom = r.fBottom;
+ }
+
+ friend bool operator==(const GrIRect& a, const GrIRect& b) {
+ return 0 == memcmp(&a, &b, sizeof(a));
+ }
+
+ friend bool operator!=(const GrIRect& a, const GrIRect& b) {
+ return 0 != memcmp(&a, &b, sizeof(a));
+ }
+
+ bool equalsLTRB(int l, int t, int r, int b) const {
+ return fLeft == l && fTop == t &&
+ fRight == r && fBottom == b;
+ }
+ bool equalsXYWH(int x, int y, int w, int h) const {
+ return fLeft == x && fTop == y &&
+ this->width() == w && this->height() == h;
+ }
+
+ bool contains(const GrIRect& r) const {
+ return fLeft <= r.fLeft &&
+ fRight >= r.fRight &&
+ fTop <= r.fTop &&
+ fBottom >= r.fBottom;
+ }
+};
+
+struct GrIRect16 {
+ int16_t fLeft, fTop, fRight, fBottom;
+
+ int width() const { return fRight - fLeft; }
+ int height() const { return fBottom - fTop; }
+ int area() const { return this->width() * this->height(); }
+ bool isEmpty() const { return fLeft >= fRight || fTop >= fBottom; }
+
+ void set(const GrIRect& r) {
+ fLeft = GrToS16(r.fLeft);
+ fTop = GrToS16(r.fTop);
+ fRight = GrToS16(r.fRight);
+ fBottom = GrToS16(r.fBottom);
+ }
+};
+
+/**
+ * 2D Rect struct
+ */
+struct GrRect {
+ GrScalar fLeft, fTop, fRight, fBottom;
+
+ /**
+ * Uninitialized rectangle.
+ */
+ GrRect() {}
+
+ /**
+ * Initialize a rectangle to a point.
+ * @param pt the point used to initialize the rectanglee.
+ */
+ GrRect(GrPoint pt) {
+ setToPoint(pt);
+ }
+
+ GrRect(GrScalar left, GrScalar top, GrScalar right, GrScalar bottom) {
+ fLeft = left;
+ fTop = top;
+ fRight = right;
+ fBottom = bottom;
+ }
+
+ explicit GrRect(const GrIRect& src) {
+ fLeft = GrIntToScalar(src.fLeft);
+ fTop = GrIntToScalar(src.fTop);
+ fRight = GrIntToScalar(src.fRight);
+ fBottom = GrIntToScalar(src.fBottom);
+ }
+
+ GrScalar x() const { return fLeft; }
+ GrScalar y() const { return fTop; }
+ GrScalar width() const { return fRight - fLeft; }
+ GrScalar height() const { return fBottom - fTop; }
+
+ GrScalar left() const { return fLeft; }
+ GrScalar top() const { return fTop; }
+ GrScalar right() const { return fRight; }
+ GrScalar bottom() const { return fBottom; }
+
+ GrScalar diagonalLengthSqd() const {
+ GrScalar w = width();
+ GrScalar h = height();
+ return GrMul(w, w) + GrMul(h, h);
+ }
+
+ GrScalar diagonalLength() const {
+ // TODO: fixed point sqrt
+ return GrFloatToScalar(sqrtf(GrScalarToFloat(diagonalLengthSqd())));
+ }
+
+ /**
+ * Returns true if the width or height is <= 0
+ */
+ bool isEmpty() const {
+ return fLeft >= fRight || fTop >= fBottom;
+ }
+
+ void setEmpty() {
+ fLeft = fTop = fRight = fBottom = 0;
+ }
+
+ /**
+ * returns true if the rectangle is inverted either in x or y
+ */
+ bool isInverted() const {
+ return (fLeft > fRight) || (fTop > fBottom);
+ }
+
+ /**
+ * Initialize a rectangle to a point.
+ * @param pt the point used to initialize the rectangle.
+ */
+ void setToPoint(const GrPoint& pt) {
+ fLeft = pt.fX;
+ fTop = pt.fY;
+ fRight = pt.fX;
+ fBottom = pt.fY;
+ }
+
+ void set(const GrIRect& r) {
+ fLeft = GrIntToScalar(r.fLeft);
+ fTop = GrIntToScalar(r.fTop);
+ fRight = GrIntToScalar(r.fRight);
+ fBottom = GrIntToScalar(r.fBottom);
+ }
+
+ void roundOut(GrIRect* r) const {
+ r->setLTRB(GrScalarFloorToInt(fLeft),
+ GrScalarFloorToInt(fTop),
+ GrScalarCeilToInt(fRight),
+ GrScalarCeilToInt(fBottom));
+ }
+
+ /**
+ * Set the rect to the union of the array of points. If the array is empty
+ * the rect will be empty [0,0,0,0]
+ */
+ void setBounds(const GrPoint pts[], int count);
+
+ /**
+ * Make the largest representable rectangle
+ * Set the rect to fLeft = fTop = GR_ScalarMin and
+ * fRight = fBottom = GR_ScalarMax.
+ */
+ void setLargest() {
+ fLeft = fTop = GR_ScalarMin;
+ fRight = fBottom = GR_ScalarMax;
+ }
+
+ /**
+ Set the rect to fLeft = fTop = GR_ScalarMax and
+ fRight = fBottom = GR_ScalarMin.
+ Useful for initializing a bounding rectangle.
+ */
+ void setLargestInverted() {
+ fLeft = fTop = GR_ScalarMax;
+ fRight = fBottom = GR_ScalarMin;
+ }
+
+ void setLTRB(GrScalar left,
+ GrScalar top,
+ GrScalar right,
+ GrScalar bottom) {
+ fLeft = left;
+ fTop = top;
+ fRight = right;
+ fBottom = bottom;
+ }
+
+ void setXYWH(GrScalar x, GrScalar y, GrScalar width, GrScalar height) {
+ fLeft = x;
+ fTop = y;
+ fRight = x + width;
+ fBottom = y + height;
+ }
+
+ /**
+ Expand the edges of the rectangle to include a point.
+ Useful for constructing a bounding rectangle.
+ @param pt the point used to grow the rectangle.
+ */
+ void growToInclude(const GrPoint& pt) {
+ fLeft = GrMin(pt.fX, fLeft);
+ fRight = GrMax(pt.fX, fRight);
+
+ fTop = GrMin(pt.fY, fTop);
+ fBottom = GrMax(pt.fY, fBottom);
+ }
+
+ /**
+ * Assigns 4 sequential points in order to construct a counter-clockwise
+ * triangle fan, given the corners of this rect. Returns the address of
+ * the next point, treating pts as an array.
+ */
+ GrPoint* setRectFan(GrPoint pts[4]) const {
+ pts->setRectFan(fLeft, fTop, fRight, fBottom);
+ return pts + 4;
+ }
+};
+
+#endif
+
diff --git a/gpu/include/GrRectanizer.h b/gpu/include/GrRectanizer.h
new file mode 100644
index 0000000000..50bb8fed24
--- /dev/null
+++ b/gpu/include/GrRectanizer.h
@@ -0,0 +1,64 @@
+/*
+ Copyright 2010 Google Inc.
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ */
+
+
+#ifndef GrRectanizer_DEFINED
+#define GrRectanizer_DEFINED
+
+#include "GrRect.h"
+#include "GrTDArray.h"
+
+class GrRectanizerPurgeListener {
+public:
+ virtual ~GrRectanizerPurgeListener() {}
+
+ virtual void notifyPurgeStrip(void*, int yCoord) = 0;
+};
+
+class GrRectanizer {
+public:
+ GrRectanizer(int width, int height) : fWidth(width), fHeight(height) {
+ GrAssert(width >= 0);
+ GrAssert(height >= 0);
+ }
+
+ virtual ~GrRectanizer() {}
+
+ int width() const { return fWidth; }
+ int height() const { return fHeight; }
+
+ virtual bool addRect(int width, int height, GrIPoint16* loc) = 0;
+ virtual float percentFull() const = 0;
+
+ // return the Y-coordinate of a strip that should be purged, given height
+ // i.e. return the oldest such strip, or some other criteria. Return -1
+ // if there is no candidate
+ virtual int stripToPurge(int height) const = 0;
+ virtual void purgeStripAtY(int yCoord) = 0;
+
+ /**
+ * Our factory, which returns the subclass du jour
+ */
+ static GrRectanizer* Factory(int width, int height);
+
+private:
+ int fWidth;
+ int fHeight;
+};
+
+#endif
+
+
diff --git a/gpu/include/GrRefCnt.h b/gpu/include/GrRefCnt.h
new file mode 100644
index 0000000000..7204aff198
--- /dev/null
+++ b/gpu/include/GrRefCnt.h
@@ -0,0 +1,125 @@
+/*
+ Copyright 2010 Google Inc.
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ */
+
+
+#ifndef GrRefCnt_DEFINED
+#define GrRefCnt_DEFINED
+
+#include "GrTypes.h"
+#include "GrNoncopyable.h"
+
+/**
+ * Base class for reference counting. When an object is first instantiated,
+ * its reference count is 1. If the object may be null, use GrSafeRef() and
+ * GrSafeUnref().
+ *
+ * It is an error (though only checked for in the debug build) to call unref()
+ * such that the reference count becomes 0.
+ */
+class GrRefCnt : GrNoncopyable {
+public:
+ GrRefCnt() : fRefCnt(1) {}
+ virtual ~GrRefCnt() {
+ GrAssert(1 == fRefCnt);
+#if GR_DEBUG
+ fRefCnt = 0; // force validate() to trigger if called afterwards
+#endif
+ }
+
+ int32_t refcnt() const { return fRefCnt; }
+
+ void ref() const {
+ GrAssert(fRefCnt > 0);
+ ++fRefCnt;
+ }
+
+ void unref() const {
+ GrAssert(fRefCnt > 0);
+ if (1 == fRefCnt) {
+ delete this;
+ } else {
+ --fRefCnt;
+ }
+ }
+
+#if GR_DEBUG
+ void validate() const {
+ GrAssert(fRefCnt > 0);
+ }
+#else
+ void validate() const {}
+#endif
+
+private:
+ mutable int32_t fRefCnt;
+};
+
+///////////////////////////////////////////////////////////////////////////////
+
+/**
+ * Call with instance/subclass of GrRefCnt. This does nothing if obj is null,
+ * but otherwise it calls ref().
+ */
+static inline void GrSafeRef(const GrRefCnt* obj) {
+ if (obj) {
+ obj->ref();
+ }
+}
+
+/**
+ * Call with instance/subclass of GrRefCnt. This does nothing if obj is null,
+ * but otherwise it calls unref().
+ */
+static inline void GrSafeUnref(const GrRefCnt* obj) {
+ if (obj) {
+ obj->unref();
+ }
+}
+
+/**
+ * Assigns src to dst, checking for NULLs in each, and correctly incrementing
+ * the reference count of src, and decrementing the reference count of dst
+ */
+static inline void GrSafeAssign(GrRefCnt*& dst, GrRefCnt* src) {
+ if (src) {
+ src->ref();
+ }
+ if (dst) {
+ dst->unref();
+ }
+ dst = src;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+class GrAutoRef : GrNoncopyable {
+public:
+ GrAutoRef(GrRefCnt* obj) : fObj(obj) { GrSafeRef(obj); }
+ ~GrAutoRef() { GrSafeUnref(fObj); }
+private:
+ GrRefCnt* fObj;
+};
+
+class GrAutoUnref : GrNoncopyable {
+public:
+ GrAutoUnref(GrRefCnt* obj) : fObj(obj) {}
+ ~GrAutoUnref() { GrSafeUnref(fObj); }
+private:
+ GrRefCnt* fObj;
+};
+
+#endif
+
diff --git a/gpu/include/GrSamplerState.h b/gpu/include/GrSamplerState.h
new file mode 100644
index 0000000000..06c2346d93
--- /dev/null
+++ b/gpu/include/GrSamplerState.h
@@ -0,0 +1,130 @@
+/*
+ Copyright 2010 Google Inc.
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ */
+
+
+#ifndef GrSamplerState_DEFINED
+#define GrSamplerState_DEFINED
+
+#include "GrTypes.h"
+
+class GrSamplerState {
+public:
+ enum SampleMode {
+ kNormal_SampleMode, //!< sample color directly
+ kAlphaMod_SampleMode, //!< modulate with alpha only
+ kRadial_SampleMode, //!< treat as radial gradient
+ kRadial2_SampleMode, //!< treat as 2-point radial gradient
+ kSweep_SampleMode, //!< treat as sweep gradient
+ };
+
+ /**
+ * Describes how a texture is sampled when coordinates are outside the
+ * texture border
+ */
+ enum WrapMode {
+ kClamp_WrapMode,
+ kRepeat_WrapMode,
+ kMirror_WrapMode
+ };
+
+ /**
+ * Default sampler state is set to kClamp and no-filter
+ */
+ GrSamplerState() {
+ this->setClampNoFilter();
+ }
+
+ GrSamplerState(bool filter) {
+ fWrapX = kClamp_WrapMode;
+ fWrapY = kClamp_WrapMode;
+ fSampleMode = kNormal_SampleMode;
+ fFilter = filter;
+ }
+
+ GrSamplerState(WrapMode wx, WrapMode wy, bool filter) {
+ fWrapX = wx;
+ fWrapY = wy;
+ fSampleMode = kNormal_SampleMode;
+ fFilter = filter;
+ }
+
+ GrSamplerState(WrapMode wx, WrapMode wy, SampleMode sample, bool filter) {
+ fWrapX = wx;
+ fWrapY = wy;
+ fSampleMode = sample;
+ fFilter = filter;
+ }
+
+ WrapMode getWrapX() const { return fWrapX; }
+ WrapMode getWrapY() const { return fWrapY; }
+ SampleMode getSampleMode() const { return fSampleMode; }
+ bool isFilter() const { return fFilter; }
+
+ bool isGradient() const {
+ return kRadial_SampleMode == fSampleMode ||
+ kRadial2_SampleMode == fSampleMode ||
+ kSweep_SampleMode == fSampleMode;
+ }
+
+ void setWrapX(WrapMode mode) { fWrapX = mode; }
+ void setWrapY(WrapMode mode) { fWrapY = mode; }
+ void setSampleMode(SampleMode mode) { fSampleMode = mode; }
+ void setFilter(bool filter) { fFilter = filter; }
+
+ void setClampNoFilter() {
+ fWrapX = kClamp_WrapMode;
+ fWrapY = kClamp_WrapMode;
+ fSampleMode = kNormal_SampleMode;
+ fFilter = false;
+ }
+
+ GrScalar getRadial2CenterX1() const { return fRadial2CenterX1; }
+ GrScalar getRadial2Radius0() const { return fRadial2Radius0; }
+ bool isRadial2PosRoot() const { return fRadial2PosRoot; }
+
+ /**
+ * Sets the parameters for kRadial2_SampleMode. The texture
+ * matrix must be set so that the first point is at (0,0) and the second
+ * point lies on the x-axis. The second radius minus the first is 1 unit.
+ * The additional parameters to define the gradient are specified by this
+ * function.
+ */
+ void setRadial2Params(GrScalar centerX1, GrScalar radius0, bool posRoot) {
+ fRadial2CenterX1 = centerX1;
+ fRadial2Radius0 = radius0;
+ fRadial2PosRoot = posRoot;
+ }
+
+ static const GrSamplerState& ClampNoFilter() {
+ return gClampNoFilter;
+ }
+
+private:
+ WrapMode fWrapX;
+ WrapMode fWrapY;
+ SampleMode fSampleMode;
+ bool fFilter;
+
+ // these are undefined unless fSampleMode == kRadial2_SampleMode
+ GrScalar fRadial2CenterX1;
+ GrScalar fRadial2Radius0;
+ bool fRadial2PosRoot;
+
+ static const GrSamplerState gClampNoFilter;
+};
+
+#endif
+
diff --git a/gpu/include/GrScalar.h b/gpu/include/GrScalar.h
new file mode 100644
index 0000000000..1353fb2148
--- /dev/null
+++ b/gpu/include/GrScalar.h
@@ -0,0 +1,116 @@
+/*
+ Copyright 2010 Google Inc.
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ */
+
+
+#ifndef GrScalar_DEFINED
+#define GrScalar_DEFINED
+
+#include "GrTypes.h"
+
+#include <float.h>
+#include <math.h>
+
+#define GR_Int32Max (0x7fffffff)
+#define GR_Int32Min (0x80000000)
+
+/**
+ * Convert an int to fixed point
+ */
+#if GR_DEBUG
+ inline GrFixed GrIntToFixed(int i) {
+ GrAssert(((i & 0xffff0000) == 0xffff0000) || ((i & 0xffff0000) == 0x0));
+ return i << 16;
+ }
+#else
+ #define GrIntToFixed(i) (GrFixed)((i) << 16)
+#endif
+
+#define GR_Fixed1 (1 << 16)
+#define GR_FixedHalf (1 << 15)
+#define GR_FixedMax GR_Int32Max
+#define GR_FixedMin GR_Int32Min
+
+#define GrFixedFloorToFixed(x) ((x) & ~0xFFFF)
+#define GrFixedFloorToInt(x) ((x) >> 16)
+
+/**
+ * Convert fixed point to floating point
+ */
+#define GrFixedToFloat(x) ((x) * 0.0000152587890625f)
+
+/**
+ * Convert floating point to fixed point
+ */
+#define GrFloatToFixed(x) ((GrFixed)((x) * GR_Fixed1))
+
+inline GrFixed GrFixedAbs(GrFixed x) {
+ int32_t s = (x & 0x80000000) >> 31;
+ return (GrFixed)(((int32_t)x ^ s) - s);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+#if GR_SCALAR_IS_FIXED
+ typedef GrFixed GrScalar;
+ #define GrIntToScalar(x) GrIntToFixed(x)
+ #define GrFixedToScalar(x) (x)
+ #define GrScalarToFloat(x) GrFixedToFloat(x)
+ #define GrFloatToScalar(x) GrFloatToFixed(x)
+ #define GrScalarHalf(x) ((x) >> 1)
+ #define GrScalarAve(x,y) (((x)+(y)) >> 1)
+ #define GrScalarAbs(x) GrFixedAbs(x)
+ #define GR_Scalar1 GR_Fixed1
+ #define GR_ScalarHalf GR_FixedHalf
+ #define GR_ScalarMax GR_FixedMax
+ #define GR_ScalarMin GR_FixedMin
+#elif GR_SCALAR_IS_FLOAT
+ typedef float GrScalar;
+ #define GrIntToScalar(x) ((GrScalar)x)
+ #define GrFixedToScalar(x) GrFixedToFloat(x)
+ #define GrScalarToFloat(x) (x)
+ #define GrFloatToScalar(x) (x)
+ #define GrScalarHalf(x) ((x) * 0.5f)
+ #define GrScalarAbs(x) fabsf(x)
+ #define GrScalarAve(x,y) (((x) + (y)) * 0.5f)
+ #define GR_Scalar1 1.f
+ #define GR_ScalarHalf 0.5f
+ #define GR_ScalarMax (FLT_MAX)
+ #define GR_ScalarMin (-FLT_MAX)
+
+ static inline int32_t GrScalarFloorToInt(float x) {
+ return (int32_t)::floorf(x);
+ }
+ static inline int32_t GrScalarCeilToInt(float x) {
+ return (int32_t)::ceilf(x);
+ }
+#else
+ #error "Scalar type not defined"
+#endif
+
+/**
+ * Multiply two GrScalar values
+ */
+static inline GrScalar GrMul(GrScalar a, GrScalar b) {
+#if GR_SCALAR_IS_FLOAT
+ return a * b;
+#else
+ int64_t tmp = (int64_t)a * b;
+ return (tmp + GR_FixedHalf) >> 16;
+#endif
+}
+
+#endif
+
diff --git a/gpu/include/GrStopwatch.h b/gpu/include/GrStopwatch.h
new file mode 100644
index 0000000000..4945897431
--- /dev/null
+++ b/gpu/include/GrStopwatch.h
@@ -0,0 +1,135 @@
+/*
+ Copyright 2010 Google Inc.
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ */
+
+
+#ifndef GrStopwatch_DEFINED
+#define GrStopwatch_DEFINED
+
+#include "GrTypes.h"
+
+template <typename PLATFORM_TIMER>
+/**
+ * Base class for stopwatch. Relies on PLATFORM_TIMER for platform-specific
+ * timer functions. PLATFORM_TIMER provides:
+ * - typename TIMESTAMP : a timestamp value that can be used with Diff()
+ * - static TIMESTAMP Now() : gets current timestamp
+ * - static double Diff(const TIMESTAMP& begin, const TIMESTAMP& end) :
+ * computes delta in seconds between two timestamps
+ */
+class GrStopwatchBase {
+public:
+ /**
+ * Contructor - implicit reset()
+ */
+ GrStopwatchBase() {
+ fRunning = false;
+ fTotalElapsed = 0.0;
+ }
+
+ /**
+ * begins a new lap
+ */
+ void start() {
+ double lastLap = lapTime();
+ fTotalElapsed += lastLap;
+ fRunning = true;
+ fLastStart = PLATFORM_TIMER::Now();
+ }
+
+ /**
+ * ends current lap (or no effect if lap not started)
+ */
+ void stop() {
+ double lastLap = lapTime();
+ fTotalElapsed += lastLap;
+ fRunning = false;
+ }
+
+ /**
+ * ends current lap, resets total time
+ */
+ void reset() {
+ fRunning = false;
+ fTotalElapsed = 0.f;
+ }
+
+ /**
+ * Computes the time of all laps since last reset() including current lap
+ * if lap is still running.
+ *
+ * @return the sum time in seconds of all laps since last reset().
+ */
+ double totalTime() const {
+ return fTotalElapsed + lapTime();
+ }
+
+ /**
+ * Current lap time.
+ *
+ * @return time in seconds of current lap if one is running otherwise 0.
+ */
+ double lapTime() const {
+ if (fRunning) {
+ PLATFORM_TIMER::Timestamp now = PLATFORM_TIMER::Now();
+ return PLATFORM_TIMER::Elapsed(fLastStart, now);
+ }
+ return 0.0;
+ }
+
+private:
+ double fTotalElapsed;
+
+ typename PLATFORM_TIMER::Timestamp fLastStart;
+ bool fRunning;
+};
+
+#if GR_WIN32_BUILD
+
+ #include <Windows.h>
+
+ class GrWin32Timer {
+ public:
+ typedef LARGE_INTEGER Timestamp;
+
+ static Timestamp Now() {
+ LARGE_INTEGER now;
+ QueryPerformanceCounter(&now);
+ return now;
+ }
+
+ static double Elapsed(const Timestamp& begin, const Timestamp& end) {
+ double diff = (double)(end.QuadPart - begin.QuadPart);
+ return diff * Scale();
+ }
+ private:
+ static double Scale() {
+ static double scale;
+ if (0.0 == scale) {
+ LARGE_INTEGER freq;
+ QueryPerformanceFrequency(&freq);
+ GrAssert(0 != freq.QuadPart);
+ scale = 1 / (double) freq.QuadPart;
+ }
+ return scale;
+ }
+ };
+ typedef GrStopwatchBase<GrWin32Timer> GrStopwatch;
+#else
+ #error "Implement platform timer for stopwatch"
+#endif
+
+
+#endif
diff --git a/gpu/include/GrStringBuilder.h b/gpu/include/GrStringBuilder.h
new file mode 100644
index 0000000000..bcf124f337
--- /dev/null
+++ b/gpu/include/GrStringBuilder.h
@@ -0,0 +1,182 @@
+/*
+ Copyright 2010 Google Inc.
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ */
+
+
+#ifndef GrStringBuilder_DEFINED
+#define GrStringBuilder_DEFINED
+
+#include <GrTArray.h>
+#include <stdio.h>
+
+// Class used to concat strings together into a single string
+// See below for GrSStringBuilder subclass that has a pool of
+// stack storage (to avoid malloc).
+class GrStringBuilder {
+public:
+ GrStringBuilder() :
+ fChars() {
+ fChars.push_back() = '\0';
+ }
+
+ GrStringBuilder(const GrStringBuilder& s) :
+ fChars(s.fChars) {
+ GrAssert('\0' == s.fChars.back());
+ }
+
+ GrStringBuilder(const char* s) :
+ fChars(s, strlen(s)+1) {
+ }
+
+ GrStringBuilder(const GrStringBuilder& a, const GrStringBuilder& b) {
+ GrAssert('\0' == a.fChars.back());
+ GrAssert('\0' == b.fChars.back());
+
+ fChars.push_back_n(a.fChars.count() + b.fChars.count() - 1);
+ char* s = &fChars.front();
+ memcpy(s, &a.fChars.front(), a.fChars.count() - 1);
+ s += a.fChars.count() - 1;
+ memcpy(s, &b.fChars.front(), b.fChars.count());
+ }
+
+ GrStringBuilder& operator =(const GrStringBuilder& s) {
+ fChars = s.fChars;
+ return *this;
+ }
+
+ GrStringBuilder& operator =(const char* s) {
+ GrAssert('\0' == fChars.back());
+
+ int l = strlen(s);
+ fChars.resize_back(l + 1);
+ memcpy(&fChars.front(), s, l + 1);
+ return *this;
+ }
+
+ GrStringBuilder& operator +=(const GrStringBuilder& s) {
+ GrAssert('\0' == fChars.back());
+ GrAssert('\0' == s.fChars.back());
+ fChars.push_back_n(s.length());
+ memcpy(&fChars.fromBack(s.length()), &s.fChars.front(), s.fChars.count());
+ return *this;
+ }
+
+ GrStringBuilder& operator +=(const char* s) {
+ GrAssert('\0' == fChars.back());
+ int l = strlen(s);
+ fChars.push_back_n(l);
+ memcpy(&fChars.fromBack(l), s, l + 1);
+ return *this;
+ }
+
+ GrStringBuilder& operator +=(char c) {
+ GrAssert('\0' == fChars.back());
+ fChars.back() = c;
+ fChars.push_back() = '\0';
+ return *this;
+ }
+
+ void appendInt(int x) {
+ GR_STATIC_ASSERT(4 == sizeof(int));
+ // -, 10 digits, null char
+ char temp[12];
+ sprintf(temp, "%d", x);
+ *this += temp;
+ }
+
+ char& operator [](int i) {
+ GrAssert(i < length());
+ return fChars[i];
+ }
+
+ char operator [](int i) const {
+ GrAssert(i < length());
+ return fChars[i];
+ }
+
+ const char* cstr() const { return &fChars.front(); }
+
+ int length() const { return fChars.count() - 1; }
+
+protected:
+ // helpers for GrSStringBuilder (with storage on the stack)
+
+ GrStringBuilder(void* stackChars, int stackCount) :
+ fChars(stackCount ? stackChars : NULL,
+ stackCount) {
+ fChars.push_back() = '\0';
+ }
+
+ GrStringBuilder(void* stackChars,
+ int stackCount,
+ const GrStringBuilder& s) :
+ fChars(s.fChars,
+ (stackCount ? stackChars : NULL),
+ stackCount) {
+ }
+
+ GrStringBuilder(void* stackChars,
+ int stackCount,
+ const char* s) :
+ fChars(s,
+ strlen(s)+1,
+ stackCount ? stackChars : NULL,
+ stackCount) {
+ }
+
+ GrStringBuilder(void* stackChars,
+ int stackCount,
+ const GrStringBuilder& a,
+ const GrStringBuilder& b) :
+ fChars(stackCount ? stackChars : NULL,
+ stackCount) {
+ GrAssert('\0' == a.fChars.back());
+ GrAssert('\0' == b.fChars.back());
+
+ fChars.push_back_n(a.fChars.count() + b.fChars.count() - 1);
+ char* s = &fChars.front();
+ memcpy(s, &a.fChars.front(), a.fChars.count() - 1);
+ s += a.fChars.count() - 1;
+ memcpy(s, &b.fChars.front(), b.fChars.count());
+ }
+
+private:
+ GrTArray<char, true> fChars;
+};
+
+template <int STACK_COUNT = 128>
+class GrSStringBuilder : public GrStringBuilder {
+public:
+ GrSStringBuilder() : GrStringBuilder(fStackChars, STACK_COUNT) {}
+
+ GrSStringBuilder(const GrStringBuilder& s) : GrStringBuilder(fStackChars,
+ STACK_COUNT,
+ s) {
+ }
+
+ GrSStringBuilder(const char* s) : GrStringBuilder(fStackChars,
+ STACK_COUNT,
+ s) {
+ }
+
+ GrSStringBuilder(const GrStringBuilder& a, const GrStringBuilder& b) :
+ GrStringBuilder(fStackChars, STACK_COUNT, a, b) {
+ }
+private:
+ char fStackChars[STACK_COUNT];
+};
+
+#endif
+
diff --git a/gpu/include/GrTArray.h b/gpu/include/GrTArray.h
new file mode 100644
index 0000000000..f0d94943a9
--- /dev/null
+++ b/gpu/include/GrTArray.h
@@ -0,0 +1,298 @@
+/*
+ Copyright 2010 Google Inc.
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ */
+
+
+#ifndef GrTArray_DEFINED
+#define GrTArray_DEFINED
+
+#include <new>
+#include "GrTypes.h"
+
+// TODO: convert from uint32_t to int.
+
+// DATA_TYPE indicates that T has a trivial cons, destructor
+// and can be shallow-copied
+template <typename T, bool DATA_TYPE = false> class GrTArray {
+public:
+ GrTArray() {
+ fCount = 0;
+ fReserveCount = MIN_ALLOC_COUNT;
+ fAllocCount = 0;
+ fMemArray = NULL;
+ fPreAllocMemArray = NULL;
+ }
+
+ GrTArray(uint32_t reserveCount) {
+ fCount = 0;
+ fReserveCount = GrMax(reserveCount, (uint32_t)MIN_ALLOC_COUNT);
+ fAllocCount = fReserveCount;
+ fMemArray = GrMalloc(sizeof(T) * fReserveCount);
+ fPreAllocMemArray = NULL;
+ }
+
+ GrTArray(void* preAllocStorage, uint32_t preAllocCount) {
+ // we allow NULL,0 args and revert to the default cons. behavior
+ // this makes it possible for a owner-object to use same constructor
+ // to get either prealloc or nonprealloc behavior based using same line
+ GrAssert((NULL == preAllocStorage) == !preAllocCount);
+
+ fCount = 0;
+ fReserveCount = preAllocCount > 0 ? preAllocCount :
+ MIN_ALLOC_COUNT;
+ fAllocCount = preAllocCount;
+ fMemArray = preAllocStorage;
+ fPreAllocMemArray = preAllocStorage;
+ }
+
+ GrTArray(const GrTArray& array) {
+ fCount = array.count();
+ fReserveCount = MIN_ALLOC_COUNT;
+ fAllocCount = GrMax(fReserveCount, fCount);
+ fMemArray = GrMalloc(sizeof(T) * fAllocCount);
+ fPreAllocMemArray = NULL;
+ if (DATA_TYPE) {
+ memcpy(fMemArray, array.fMemArray, sizeof(T) * fCount);
+ } else {
+ for (uint32_t i = 0; i < fCount; ++i) {
+ new (fItemArray + i) T(array[i]);
+ }
+ }
+ }
+
+ GrTArray(const T* array, uint32_t count) {
+ fCount = count;
+ fReserveCount = MIN_ALLOC_COUNT;
+ fAllocCount = GrMax(fReserveCount, fCount);
+ fMemArray = GrMalloc(sizeof(T) * fAllocCount);
+ fPreAllocMemArray = NULL;
+ if (DATA_TYPE) {
+ memcpy(fMemArray, array, sizeof(T) * fCount);
+ } else {
+ for (uint32_t i = 0; i < fCount; ++i) {
+ new (fItemArray + i) T(array[i]);
+ }
+ }
+ }
+
+ GrTArray(const GrTArray& array,
+ void* preAllocStorage, uint32_t preAllocCount) {
+
+ // for same reason as non-copying cons we allow NULL, 0 for prealloc
+ GrAssert((NULL == preAllocStorage) == !preAllocCount);
+
+ fCount = array.count();
+ fReserveCount = preAllocCount > 0 ? preAllocCount :
+ MIN_ALLOC_COUNT;
+ fPreAllocMemArray = preAllocStorage;
+
+ if (fReserveCount >= fCount && preAllocCount) {
+ fAllocCount = fReserveCount;
+ fMemArray = preAllocStorage;
+ } else {
+ fAllocCount = GrMax(fCount, fReserveCount);
+ fMemArray = GrMalloc(fAllocCount * sizeof(T));
+ }
+
+ if (DATA_TYPE) {
+ memcpy(fMemArray, array.fMemArray, sizeof(T) * fCount);
+ } else {
+ for (uint32_t i = 0; i < fCount; ++i) {
+ new (fItemArray + i) T(array[i]);
+ }
+ }
+ }
+
+ GrTArray(const T* array, uint32_t count,
+ void* preAllocStorage, uint32_t preAllocCount) {
+
+ // for same reason as non-copying cons we allow NULL, 0 for prealloc
+ GrAssert((NULL == preAllocStorage) == !preAllocCount);
+
+ fCount = count;
+ fReserveCount = (preAllocCount > 0) ? preAllocCount :
+ MIN_ALLOC_COUNT;
+ fPreAllocMemArray = preAllocStorage;
+
+ if (fReserveCount >= fCount && preAllocCount) {
+ fAllocCount = fReserveCount;
+ fMemArray = preAllocStorage;
+ } else {
+ fAllocCount = GrMax(fCount, fReserveCount);
+ fMemArray = GrMalloc(fAllocCount * sizeof(T));
+ }
+
+ if (DATA_TYPE) {
+ memcpy(fMemArray, array, sizeof(T) * fCount);
+ } else {
+ for (uint32_t i = 0; i < fCount; ++i) {
+ new (fItemArray + i) T(array[i]);
+ }
+ }
+ }
+
+ GrTArray& operator =(const GrTArray& array) {
+ for (uint32_t i = 0; i < fCount; ++i) {
+ fItemArray[i].~T();
+ }
+ fCount = 0;
+ checkRealloc((int)array.count());
+ fCount = array.count();
+ if (DATA_TYPE) {
+ memcpy(fMemArray, array.fMemArray, sizeof(T) * fCount);
+ } else {
+ for (uint32_t i = 0; i < fCount; ++i) {
+ new (fItemArray + i) T(array[i]);
+ }
+ }
+ return *this;
+ }
+
+ ~GrTArray() {
+ for (uint32_t i = 0; i < fCount; ++i) {
+ fItemArray[i].~T();
+ }
+ if (fMemArray != fPreAllocMemArray) {
+ GrFree(fMemArray);
+ }
+ }
+
+ uint32_t count() const { return fCount; }
+
+ bool empty() const { return !fCount; }
+
+ T& push_back() {
+ checkRealloc(1);
+ new ((char*)fMemArray+sizeof(T)*fCount) T;
+ ++fCount;
+ return fItemArray[fCount-1];
+ }
+
+ void push_back_n(uint32_t n) {
+ checkRealloc(n);
+ for (uint32_t i = 0; i < n; ++i) {
+ new (fItemArray + fCount + i) T;
+ }
+ fCount += n;
+ }
+
+ void pop_back() {
+ GrAssert(0 != fCount);
+ --fCount;
+ fItemArray[fCount].~T();
+ checkRealloc(0);
+ }
+
+ void pop_back_n(uint32_t n) {
+ GrAssert(fCount >= n);
+ fCount -= n;
+ for (uint32_t i = 0; i < n; ++i) {
+ fItemArray[i].~T();
+ }
+ checkRealloc(0);
+ }
+
+ // pushes or pops from the back to resize
+ void resize_back(uint32_t newCount) {
+ if (newCount > fCount) {
+ push_back_n(newCount - fCount);
+ } else if (newCount < fCount) {
+ pop_back_n(fCount - newCount);
+ }
+ }
+
+ T& operator[] (uint32_t i) {
+ GrAssert(i < fCount);
+ return fItemArray[i];
+ }
+
+ const T& operator[] (uint32_t i) const {
+ GrAssert(i < fCount);
+ return fItemArray[i];
+ }
+
+ T& front() { GrAssert(fCount); return fItemArray[0];}
+
+ const T& front() const { GrAssert(fCount); return fItemArray[0];}
+
+ T& back() { GrAssert(fCount); return fItemArray[fCount - 1];}
+
+ const T& back() const { GrAssert(fCount); return fItemArray[fCount - 1];}
+
+ T& fromBack(uint32_t i) {
+ GrAssert(i < fCount);
+ return fItemArray[fCount - i - 1];
+ }
+
+ const T& fromBack(uint32_t i) const {
+ GrAssert(i < fCount);
+ return fItemArray[fCount - i - 1];
+ }
+
+private:
+ static const uint32_t MIN_ALLOC_COUNT = 8;
+
+ inline void checkRealloc(int32_t delta) {
+ GrAssert(-delta <= (int32_t)fCount);
+
+ uint32_t newCount = fCount + delta;
+ uint32_t fNewAllocCount = fAllocCount;
+
+ if (newCount > fAllocCount) {
+ fNewAllocCount = GrMax(newCount + ((newCount + 1) >> 1),
+ fReserveCount);
+ } else if (newCount < fAllocCount / 3) {
+ fNewAllocCount = GrMax(fAllocCount / 2, fReserveCount);
+ }
+
+ if (fNewAllocCount != fAllocCount) {
+
+ fAllocCount = fNewAllocCount;
+ char* fNewMemArray;
+
+ if (fAllocCount == fReserveCount && NULL != fPreAllocMemArray) {
+ fNewMemArray = (char*) fPreAllocMemArray;
+ } else {
+ fNewMemArray = (char*) GrMalloc(fAllocCount*sizeof(T));
+ }
+
+ if (DATA_TYPE) {
+ memcpy(fNewMemArray, fMemArray, fCount * sizeof(T));
+ } else {
+ for (uint32_t i = 0; i < fCount; ++i) {
+ new (fNewMemArray + sizeof(T) * i) T(fItemArray[i]);
+ fItemArray[i].~T();
+ }
+ }
+
+ if (fMemArray != fPreAllocMemArray) {
+ GrFree(fMemArray);
+ }
+ fMemArray = fNewMemArray;
+ }
+ }
+
+ uint32_t fReserveCount;
+ uint32_t fCount;
+ uint32_t fAllocCount;
+ void* fPreAllocMemArray;
+ union {
+ T* fItemArray;
+ void* fMemArray;
+ };
+};
+
+#endif
+
diff --git a/gpu/include/GrTBSearch.h b/gpu/include/GrTBSearch.h
new file mode 100644
index 0000000000..264ccb0dbb
--- /dev/null
+++ b/gpu/include/GrTBSearch.h
@@ -0,0 +1,53 @@
+/*
+ Copyright 2010 Google Inc.
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ */
+
+
+#ifndef GrTBSearch_DEFINED
+#define GrTBSearch_DEFINED
+
+template <typename ELEM, typename KEY>
+int GrTBSearch(const ELEM array[], int count, KEY target) {
+ GrAssert(count >= 0);
+ if (0 == count) {
+ // we should insert it at 0
+ return ~0;
+ }
+
+ int high = count - 1;
+ int low = 0;
+ while (high > low) {
+ int index = (low + high) >> 1;
+ if (LT(array[index], target)) {
+ low = index + 1;
+ } else {
+ high = index;
+ }
+ }
+
+ // check if we found it
+ if (EQ(array[high], target)) {
+ return high;
+ }
+
+ // now return the ~ of where we should insert it
+ if (LT(array[high], target)) {
+ high += 1;
+ }
+ return ~high;
+}
+
+#endif
+
diff --git a/gpu/include/GrTDArray.h b/gpu/include/GrTDArray.h
new file mode 100644
index 0000000000..092242e5fc
--- /dev/null
+++ b/gpu/include/GrTDArray.h
@@ -0,0 +1,222 @@
+/*
+ Copyright 2010 Google Inc.
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ */
+
+
+#ifndef GrTDArray_DEFINED
+#define GrTDArray_DEFINED
+
+#include "GrTypes.h"
+
+static int GrInitialArrayAllocationCount() {
+ return 4;
+}
+
+static int GrNextArrayAllocationCount(int count) {
+ return count + ((count + 1) >> 1);
+}
+
+template <typename T> class GrTDArray {
+public:
+ GrTDArray() : fArray(NULL), fAllocated(0), fCount(0) {}
+ GrTDArray(const GrTDArray& src) {
+ fCount = fAllocated = src.fCount;
+ fArray = (T*)GrMalloc(fAllocated * sizeof(T));
+ memcpy(fArray, src.fArray, fCount * sizeof(T));
+ }
+ ~GrTDArray() {
+ if (fArray) {
+ GrFree(fArray);
+ }
+ }
+
+ bool isEmpty() const { return 0 == fCount; }
+ int count() const { return fCount; }
+
+ const T& at(int index) const {
+ GrAssert((unsigned)index < (unsigned)fCount);
+ return fArray[index];
+ }
+ T& at(int index) {
+ GrAssert((unsigned)index < (unsigned)fCount);
+ return fArray[index];
+ }
+
+ const T& operator[](int index) const { return this->at(index); }
+ T& operator[](int index) { return this->at(index); }
+
+ GrTDArray& operator=(const GrTDArray& src) {
+ if (fAllocated < src.fCount) {
+ fAllocated = src.fCount;
+ GrFree(fArray);
+ fArray = (T*)GrMalloc(fAllocated * sizeof(T));
+ }
+ fCount = src.fCount;
+ memcpy(fArray, src.fArray, fCount * sizeof(T));
+ return *this;
+ }
+
+ void reset() {
+ if (fArray) {
+ GrFree(fArray);
+ fArray = NULL;
+ }
+ fAllocated = fCount = 0;
+ }
+
+ T* begin() const { return fArray; }
+ T* end() const { return fArray + fCount; }
+ T* back() const { GrAssert(fCount); return fArray + (fCount - 1); }
+
+ T* prepend() {
+ this->growAt(0);
+ return fArray;
+ }
+
+ T* append() {
+ this->growAt(fCount);
+ return fArray + fCount - 1;
+ }
+
+ /**
+ * index may be [0..count], so that you can insert at the end (like append)
+ */
+ T* insert(int index) {
+ GrAssert((unsigned)index <= (unsigned)fCount);
+ this->growAt(index);
+ return fArray + index;
+ }
+
+ void remove(int index) {
+ GrAssert((unsigned)index < (unsigned)fCount);
+ fCount -= 1;
+ if (index < fCount) {
+ int remaining = fCount - index;
+ memmove(fArray + index, fArray + index + 1, remaining * sizeof(T));
+ }
+ }
+
+ void removeShuffle(int index) {
+ GrAssert((unsigned)index < (unsigned)fCount);
+ fCount -= 1;
+ if (index < fCount) {
+ memmove(fArray + index, fArray + fCount, sizeof(T));
+ }
+ }
+
+ // Utility iterators
+
+ /**
+ * Calls GrFree() on each element. Assumes each is NULL or was allocated
+ * with GrMalloc().
+ */
+ void freeAll() {
+ T* stop = this->end();
+ for (T* curr = this->begin(); curr < stop; curr++) {
+ GrFree(*curr);
+ }
+ this->reset();
+ }
+
+ /**
+ * Calls delete on each element. Assumes each is NULL or was allocated
+ * with new.
+ */
+ void deleteAll() {
+ T* stop = this->end();
+ for (T* curr = this->begin(); curr < stop; curr++) {
+ delete *curr;
+ }
+ this->reset();
+ }
+
+ /**
+ * Calls GrSafeUnref() on each element. Assumes each is NULL or is a
+ * subclass of GrRefCnt.
+ */
+ void unrefAll() {
+ T* stop = this->end();
+ for (T* curr = this->begin(); curr < stop; curr++) {
+ GrSafeUnref(*curr);
+ }
+ this->reset();
+ }
+
+ void visit(void visitor(T&)) const {
+ T* stop = this->end();
+ for (T* curr = this->begin(); curr < stop; curr++) {
+ if (*curr) {
+ visitor(*curr);
+ }
+ }
+ }
+
+ int find(const T& elem) const {
+ int count = this->count();
+ T* curr = this->begin();
+ for (int i = 0; i < count; i++) {
+ if (elem == curr[i]) {
+ return i;
+ }
+ }
+ return -1;
+ }
+
+ friend bool operator==(const GrTDArray<T>& a, const GrTDArray<T>& b) {
+ return a.count() == b.count() &&
+ (0 == a.count() ||
+ 0 == memcmp(a.begin(), b.begin(), a.count() * sizeof(T)));
+ }
+ friend bool operator!=(const GrTDArray<T>& a, const GrTDArray<T>& b) {
+ return !(a == b);
+ }
+
+private:
+ T* fArray;
+ int fAllocated, fCount;
+
+ // growAt will increment fCount, reallocate fArray (as needed), and slide
+ // the contents of fArray to make a hole for new data at index.
+ void growAt(int index) {
+ GrAssert(fCount <= fAllocated);
+ if (0 == fAllocated) {
+ fAllocated = GrInitialArrayAllocationCount();
+ fArray = (T*)GrMalloc(fAllocated * sizeof(T));
+ } else if (fCount == fAllocated) {
+ fAllocated = GrNextArrayAllocationCount(fAllocated);
+ T* newArray = (T*)GrMalloc(fAllocated * sizeof(T));
+ memcpy(newArray, fArray, index * sizeof(T));
+ memcpy(newArray + index + 1, fArray + index,
+ (fCount - index) * sizeof(T));
+ GrFree(fArray);
+ fArray = newArray;
+ } else {
+ // check that we're not just appending
+ if (index < fCount) {
+ memmove(fArray + index + 1, fArray + index,
+ (fCount - index) * sizeof(T));
+ }
+ }
+ GrAssert(fCount < fAllocated);
+ fCount += 1;
+ }
+};
+
+extern void* GrTDArray_growAt(void*, int* allocated, int& count, int index,
+ size_t);
+
+
+#endif
+
diff --git a/gpu/include/GrTHashCache.h b/gpu/include/GrTHashCache.h
new file mode 100644
index 0000000000..510f9ab205
--- /dev/null
+++ b/gpu/include/GrTHashCache.h
@@ -0,0 +1,226 @@
+/*
+ Copyright 2010 Google Inc.
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ */
+
+
+#ifndef GrTHashCache_DEFINED
+#define GrTHashCache_DEFINED
+
+#include "GrTDArray.h"
+
+/**
+ * Key needs
+ * static bool EQ(const Entry&, const HashKey&);
+ * static bool LT(const Entry&, const HashKey&);
+ * uint32_t getHash() const;
+ *
+ * Allows duplicate key entries but on find you may get
+ * any of the duplicate entries returned.
+ */
+template <typename T, typename Key, size_t kHashBits> class GrTHashTable {
+public:
+ GrTHashTable() { Gr_bzero(fHash, sizeof(fHash)); }
+ ~GrTHashTable() {}
+
+ int count() const { return fSorted.count(); }
+ T* find(const Key&) const;
+ // return true if key was unique when inserted.
+ bool insert(const Key&, T*);
+ void remove(const Key&, const T*);
+ T* removeAt(int index, uint32_t hash);
+ void removeAll();
+ void deleteAll();
+ void unrefAll();
+
+ /**
+ * Return the index for the element, using a linear search.
+ */
+ int slowFindIndex(T* elem) const { return fSorted.find(elem); }
+
+#if GR_DEBUG
+ void validate() const;
+ bool contains(T*) const;
+#endif
+
+ // testing
+ const GrTDArray<T*>& getArray() const { return fSorted; }
+private:
+ enum {
+ kHashCount = 1 << kHashBits,
+ kHashMask = kHashCount - 1
+ };
+ static unsigned hash2Index(uint32_t hash) {
+ hash ^= hash >> 16;
+ if (kHashBits <= 8) {
+ hash ^= hash >> 8;
+ }
+ return hash & kHashMask;
+ }
+
+ mutable T* fHash[kHashCount];
+ GrTDArray<T*> fSorted;
+
+ // search fSorted, and return the found index, or ~index of where it
+ // should be inserted
+ int searchArray(const Key&) const;
+};
+
+///////////////////////////////////////////////////////////////////////////////
+
+template <typename T, typename Key, size_t kHashBits>
+int GrTHashTable<T, Key, kHashBits>::searchArray(const Key& key) const {
+ int count = fSorted.count();
+ if (0 == count) {
+ // we should insert it at 0
+ return ~0;
+ }
+
+ const T* const* array = fSorted.begin();
+ int high = count - 1;
+ int low = 0;
+ while (high > low) {
+ int index = (low + high) >> 1;
+ if (Key::LT(*array[index], key)) {
+ low = index + 1;
+ } else {
+ high = index;
+ }
+ }
+
+ // check if we found it
+ if (Key::EQ(*array[high], key)) {
+ // above search should have found the first occurrence if there
+ // are multiple.
+ GrAssert(0 == high || Key::LT(*array[high - 1], key));
+ return high;
+ }
+
+ // now return the ~ of where we should insert it
+ if (Key::LT(*array[high], key)) {
+ high += 1;
+ }
+ return ~high;
+}
+
+template <typename T, typename Key, size_t kHashBits>
+T* GrTHashTable<T, Key, kHashBits>::find(const Key& key) const {
+ int hashIndex = hash2Index(key.getHash());
+ T* elem = fHash[hashIndex];
+
+ if (NULL == elem || !Key::EQ(*elem, key)) {
+ // bsearch for the key in our sorted array
+ int index = this->searchArray(key);
+ if (index < 0) {
+ return NULL;
+ }
+ elem = fSorted[index];
+ // update the hash
+ fHash[hashIndex] = elem;
+ }
+ return elem;
+}
+
+template <typename T, typename Key, size_t kHashBits>
+bool GrTHashTable<T, Key, kHashBits>::insert(const Key& key, T* elem) {
+ int index = this->searchArray(key);
+ bool first = index < 0;
+ if (first) {
+ // turn it into the actual index
+ index = ~index;
+ }
+ // add it to our array
+ *fSorted.insert(index) = elem;
+ // update our hash table (overwrites any dupe's position in the hash)
+ fHash[hash2Index(key.getHash())] = elem;
+ return first;
+}
+
+template <typename T, typename Key, size_t kHashBits>
+void GrTHashTable<T, Key, kHashBits>::remove(const Key& key, const T* elem) {
+ int index = hash2Index(key.getHash());
+ if (fHash[index] == elem) {
+ fHash[index] = NULL;
+ }
+
+ // remove from our sorted array
+ index = this->searchArray(key);
+ GrAssert(index >= 0);
+ // if there are multiple matches searchArray will give us the first match
+ // march forward until we find elem.
+ while (elem != fSorted[index]) {
+ ++index;
+ GrAssert(index < fSorted.count());
+ }
+ GrAssert(elem == fSorted[index]);
+ fSorted.remove(index);
+}
+
+template <typename T, typename Key, size_t kHashBits>
+T* GrTHashTable<T, Key, kHashBits>::removeAt(int elemIndex, uint32_t hash) {
+ int hashIndex = hash2Index(hash);
+ if (fHash[hashIndex] == fSorted[elemIndex]) {
+ fHash[hashIndex] = NULL;
+ }
+ // remove from our sorted array
+ T* elem = fSorted[elemIndex];
+ fSorted.remove(elemIndex);
+ return elem;
+}
+
+template <typename T, typename Key, size_t kHashBits>
+void GrTHashTable<T, Key, kHashBits>::removeAll() {
+ fSorted.reset();
+ Gr_bzero(fHash, sizeof(fHash));
+}
+
+template <typename T, typename Key, size_t kHashBits>
+void GrTHashTable<T, Key, kHashBits>::deleteAll() {
+ fSorted.deleteAll();
+ Gr_bzero(fHash, sizeof(fHash));
+}
+
+template <typename T, typename Key, size_t kHashBits>
+void GrTHashTable<T, Key, kHashBits>::unrefAll() {
+ fSorted.unrefAll();
+ Gr_bzero(fHash, sizeof(fHash));
+}
+
+#if GR_DEBUG
+template <typename T, typename Key, size_t kHashBits>
+void GrTHashTable<T, Key, kHashBits>::validate() const {
+ for (size_t i = 0; i < GR_ARRAY_COUNT(fHash); i++) {
+ if (fHash[i]) {
+ unsigned hashIndex = hash2Index(Key::GetHash(*fHash[i]));
+ GrAssert(hashIndex == i);
+ }
+ }
+
+ int count = fSorted.count();
+ for (int i = 1; i < count; i++) {
+ GrAssert(Key::LT(*fSorted[i - 1], *fSorted[i]) ||
+ Key::EQ(*fSorted[i - 1], *fSorted[i]));
+ }
+}
+
+template <typename T, typename Key, size_t kHashBits>
+bool GrTHashTable<T, Key, kHashBits>::contains(T* elem) const {
+ int index = fSorted.find(elem);
+ return index >= 0;
+}
+
+#endif
+
+#endif
+
diff --git a/gpu/include/GrTLList.h b/gpu/include/GrTLList.h
new file mode 100644
index 0000000000..1f59635ad4
--- /dev/null
+++ b/gpu/include/GrTLList.h
@@ -0,0 +1,61 @@
+/*
+ Copyright 2010 Google Inc.
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ */
+
+
+#ifndef GrTLList_DEFINED
+#define GrTLList_DEFINED
+
+#include "GrNoncopyable.h"
+
+template <typename T> class GrTLList : GrNoncopyable {
+public:
+ class Entry {
+ Entry* fPrev;
+ Entry* fNext;
+ };
+
+ GrTLList() : fHead(NULL), fTail(NULL) {}
+#if GR_DEBUG
+ ~GrTLList() {
+ GrAssert(NULL == fHead);
+ GrAssert(NULL == ftail);
+ }
+#endif
+
+ T* head() const { return fHead; }
+ T* tail() const { return fTail; }
+
+ void addToHead(T*);
+ void addToTail(T*);
+ void removeFromList(T*);
+
+private:
+ Entry* fHead;
+ Entry* fTail;
+
+ friend class Entry;
+};
+
+
+class Parent {
+ GrTDLList<Child> fList;
+};
+
+class Child : public GrTLList::Entry<Child> {
+};
+
+#endif
+
diff --git a/gpu/include/GrTextContext.h b/gpu/include/GrTextContext.h
new file mode 100644
index 0000000000..6b7446b4be
--- /dev/null
+++ b/gpu/include/GrTextContext.h
@@ -0,0 +1,67 @@
+/*
+ Copyright 2010 Google Inc.
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ */
+
+
+#ifndef GrTextContext_DEFINED
+#define GrTextContext_DEFINED
+
+#include "GrGlyph.h"
+#include "GrGpuVertex.h"
+
+class GrContext;
+class GrTextStrike;
+class GrFontScaler;
+
+class GrTextContext {
+public:
+ GrTextContext(GrContext*, const GrMatrix* extMatrix = NULL);
+ ~GrTextContext();
+
+ void drawPackedGlyph(GrGlyph::PackedID, GrFixed left, GrFixed top,
+ GrFontScaler*);
+
+ void flush(); // optional; automatically called by destructor
+
+private:
+ GrContext* fContext;
+ GrDrawTarget* fDrawTarget;
+
+ GrMatrix fExtMatrix;
+ GrFontScaler* fScaler;
+ GrTextStrike* fStrike;
+
+ inline void flushGlyphs();
+
+ enum {
+ kMinRequestedGlyphs = 1,
+ kDefaultRequestedGlyphs = 64,
+ kMinRequestedVerts = kMinRequestedGlyphs * 4,
+ kDefaultRequestedVerts = kDefaultRequestedGlyphs * 4,
+ };
+
+ GrGpuTextVertex* fVertices;
+
+ int32_t fMaxVertices;
+ GrTexture* fCurrTexture;
+ int fCurrVertex;
+
+ GrIRect fClipRect;
+ GrMatrix fOrigViewMatrix; // restore previous viewmatrix
+};
+
+#endif
+
+
diff --git a/gpu/include/GrTextStrike.h b/gpu/include/GrTextStrike.h
new file mode 100644
index 0000000000..abafa57130
--- /dev/null
+++ b/gpu/include/GrTextStrike.h
@@ -0,0 +1,119 @@
+/*
+ Copyright 2010 Google Inc.
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ */
+
+
+#ifndef GrTextStrike_DEFINED
+#define GrTextStrike_DEFINED
+
+#include "GrAllocPool.h"
+#include "GrFontScaler.h"
+#include "GrTHashCache.h"
+#include "GrPoint.h"
+#include "GrGlyph.h"
+
+class GrAtlasMgr;
+class GrFontCache;
+class GrGpu;
+class GrFontPurgeListener;
+
+/**
+ * The textcache maps a hostfontscaler instance to a dictionary of
+ * glyphid->strike
+ */
+class GrTextStrike {
+public:
+ GrTextStrike(GrFontCache*, const GrKey* fontScalerKey, GrAtlasMgr*);
+ ~GrTextStrike();
+
+ const GrKey* getFontScalerKey() const { return fFontScalerKey; }
+ GrFontCache* getFontCache() const { return fFontCache; }
+
+ inline GrGlyph* getGlyph(GrGlyph::PackedID, GrFontScaler*);
+ bool getGlyphAtlas(GrGlyph*, GrFontScaler*);
+
+ // testing
+ int countGlyphs() const { return fCache.getArray().count(); }
+ const GrGlyph* glyphAt(int index) const {
+ return fCache.getArray()[index];
+ }
+ GrAtlas* getAtlas() const { return fAtlas; }
+
+public:
+ // for LRU
+ GrTextStrike* fPrev;
+ GrTextStrike* fNext;
+
+private:
+ class Key;
+ GrTHashTable<GrGlyph, Key, 7> fCache;
+ const GrKey* fFontScalerKey;
+ GrTAllocPool<GrGlyph> fPool;
+
+ GrFontCache* fFontCache;
+ GrAtlasMgr* fAtlasMgr;
+ GrAtlas* fAtlas; // linklist
+
+ GrGlyph* generateGlyph(GrGlyph::PackedID packed, GrFontScaler* scaler);
+ // returns true if after the purge, the strike is empty
+ bool purgeAtlasAtY(GrAtlas* atlas, int yCoord);
+
+ friend class GrFontCache;
+};
+
+class GrFontCache {
+public:
+ GrFontCache(GrGpu*);
+ ~GrFontCache();
+
+ inline GrTextStrike* getStrike(GrFontScaler*);
+
+ void freeAll();
+ void abandonAll();
+
+ void purgeExceptFor(GrTextStrike*);
+
+ // testing
+ int countStrikes() const { return fCache.getArray().count(); }
+ const GrTextStrike* strikeAt(int index) const {
+ return fCache.getArray()[index];
+ }
+ GrTextStrike* getHeadStrike() const { return fHead; }
+
+#if GR_DEBUG
+ void validate() const;
+#else
+ void validate() const {}
+#endif
+
+private:
+ friend class GrFontPurgeListener;
+
+ class Key;
+ GrTHashTable<GrTextStrike, Key, 8> fCache;
+ // for LRU
+ GrTextStrike* fHead;
+ GrTextStrike* fTail;
+
+ GrGpu* fGpu;
+ GrAtlasMgr* fAtlasMgr;
+
+
+ GrTextStrike* generateStrike(GrFontScaler*, const Key&);
+ inline void detachStrikeFromList(GrTextStrike*);
+};
+
+#endif
+
diff --git a/gpu/include/GrTexture.h b/gpu/include/GrTexture.h
new file mode 100644
index 0000000000..71a58e621b
--- /dev/null
+++ b/gpu/include/GrTexture.h
@@ -0,0 +1,213 @@
+/*
+ Copyright 2010 Google Inc.
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ */
+
+
+#ifndef GrTexture_DEFINED
+#define GrTexture_DEFINED
+
+#include "GrRefCnt.h"
+
+class GrTexture;
+
+/**
+ * GrRenderTarget represents a 2D buffer of pixels that can be rendered to.
+ * A context's render target is set by setRenderTarget(). Render targets are
+ * created by a createTexture with the kRenderTarget_TextureFlag flag.
+ * Additionally, the rendering destination set in the underlying 3D API at the
+ * time of GrContext's creation can be retrieved by calling
+ * currentRenderTarget() after creation before any calles to setRenderTarget().
+ */
+class GrRenderTarget : public GrRefCnt {
+public:
+ /**
+ * @return the width of the rendertarget
+ */
+ virtual uint32_t width() const = 0;
+ /**
+ * @return the height of the rendertarget
+ */
+ virtual uint32_t height() const = 0;
+
+ /**
+ * @return the texture associated with the rendertarget, may be NULL.
+ */
+ GrTexture* asTexture() {return fTexture;}
+
+protected:
+ GrRenderTarget(GrTexture* texture) : fTexture(texture) {}
+ GrTexture* fTexture;
+};
+
+class GrTexture : public GrRefCnt {
+public:
+ enum PixelConfig {
+ kUnknown_PixelConfig,
+ kAlpha_8_PixelConfig,
+ kIndex_8_PixelConfig,
+ kRGB_565_PixelConfig,
+ kRGBA_4444_PixelConfig, //!< premultiplied
+ kRGBA_8888_PixelConfig, //!< premultiplied
+ kRGBX_8888_PixelConfig, //!< treat the alpha channel as opaque
+ };
+ static size_t BytesPerPixel(PixelConfig);
+ static bool PixelConfigIsOpaque(PixelConfig);
+
+protected:
+ GrTexture(uint32_t contentWidth,
+ uint32_t contentHeight,
+ uint32_t allocWidth,
+ uint32_t allocHeight,
+ PixelConfig config) :
+ fAllocWidth(allocWidth),
+ fAllocHeight(allocHeight),
+ fContentWidth(contentWidth),
+ fContentHeight(contentHeight),
+ fConfig(config) {
+ // only make sense if alloc size is pow2
+ fShiftFixedX = 31 - Gr_clz(allocWidth);
+ fShiftFixedY = 31 - Gr_clz(allocHeight);
+ }
+public:
+ virtual ~GrTexture();
+
+ /**
+ * Retrieves the width of the content area of the texture. Reflects the
+ * width passed to GrGpu::createTexture().
+ *
+ * @return the width in texels
+ */
+ uint32_t contentWidth() const { return fContentWidth; }
+ /**
+ * Retrieves the height of the content area of the texture. Reflects the
+ * height passed to GrGpu::createTexture().
+ *
+ * @return the height in texels
+ */
+ uint32_t contentHeight() const { return fContentHeight; }
+
+ /**
+ * Retrieves the texture width actually allocated in texels.
+ *
+ * @return the width in texels
+ */
+ uint32_t allocWidth() const { return fAllocWidth; }
+ /**
+ * Retrieves the texture height actually allocated in texels.
+ *
+ * @return the height in texels
+ */
+ uint32_t allocHeight() const { return fAllocHeight; }
+
+ /**
+ * Convert from texels to normalized texture coords for POT textures
+ * only.
+ */
+ GrFixed normalizeFixedX(GrFixed x) const { GrAssert(GrIsPow2(fAllocWidth));
+ return x >> fShiftFixedX; }
+ GrFixed normalizeFixedY(GrFixed y) const { GrAssert(GrIsPow2(fAllocHeight));
+ return y >> fShiftFixedY; }
+
+ /**
+ * Retrieves the pixel config specified when the texture was created.
+ */
+ PixelConfig config() const { return fConfig; }
+
+ /**
+ * The number of bytes used by the texture
+ */
+ size_t sizeInBytes() const {
+ return fAllocWidth * fAllocHeight * BytesPerPixel(fConfig);
+ }
+
+ /**
+ * Updates a subrectangle of texels in the texture.
+ *
+ * @param x left edge of rectangle to update
+ * @param y top edge of rectangle to update
+ * @param width width of rectangle to update
+ * @param height height of rectangle to update
+ * @param srcData width*height texels of data in same format that was used
+ * at texture creation.
+ */
+ virtual void uploadTextureData(uint32_t x,
+ uint32_t y,
+ uint32_t width,
+ uint32_t height,
+ const void* srcData) = 0;
+ /**
+ * Indicates that GPU context in which this texture was created is destroyed
+ * and that Ganesh should not attempt to free the texture with the
+ * underlying API.
+ */
+ virtual void abandon() = 0;
+
+ /**
+ * Queries whether the texture was created as a render target.
+ *
+ * Use asRenderTarget() to use the texture as a render target if this
+ * returns true.
+ *
+ * @return true if the texture was created as a render target.
+ */
+ virtual bool isRenderTarget() const = 0;
+
+ /**
+ * Retrieves the render target underlying this texture that can be passed to
+ * GrGpu::setRenderTarget().
+ *
+ * If isRenderTarget() is false then the returned handle is undefined.
+ *
+ * @return handle to render target or undefined if the texture is not a
+ * render target
+ */
+ virtual GrRenderTarget* asRenderTarget() = 0;
+
+ /**
+ * Removes the "rendertargetness" from a texture. This may or may not
+ * actually do anything with the underlying 3D API.
+ */
+ virtual void removeRenderTarget() = 0;
+
+ /**
+ * Return the native ID or handle to the texture, depending on the
+ * platform. e.g. on opengl, return the texture ID.
+ */
+ virtual intptr_t getTextureHandle() = 0;
+
+#if GR_DEBUG
+ void validate() const {
+ this->INHERITED::validate();
+ }
+#else
+ void validate() const {}
+#endif
+
+private:
+ uint32_t fAllocWidth;
+ uint32_t fAllocHeight;
+ uint32_t fContentWidth;
+ uint32_t fContentHeight;
+ // these two shift a fixed-point value into normalized coordinates
+ // for this texture if the texture is power of two sized.
+ int fShiftFixedX;
+ int fShiftFixedY;
+ PixelConfig fConfig;
+
+ typedef GrRefCnt INHERITED;
+};
+
+#endif
+
diff --git a/gpu/include/GrTextureCache.h b/gpu/include/GrTextureCache.h
new file mode 100644
index 0000000000..e3d4f0a100
--- /dev/null
+++ b/gpu/include/GrTextureCache.h
@@ -0,0 +1,289 @@
+/*
+ Copyright 2010 Google Inc.
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ */
+
+
+#ifndef GrTextureCache_DEFINED
+#define GrTextureCache_DEFINED
+
+#include "GrTypes.h"
+#include "GrTHashCache.h"
+
+class GrTexture;
+
+// return true if a<b, or false if b<a
+//
+#define RET_IF_LT_OR_GT(a, b) \
+ do { \
+ if ((a) < (b)) { \
+ return true; \
+ } \
+ if ((b) < (a)) { \
+ return false; \
+ } \
+ } while (0)
+
+/**
+ * Helper class for GrTextureCache, the Key is used to identify src data for
+ * a texture. It is identified by 2 32bit data fields which can hold any
+ * data (uninterpreted by the cache) and a width/height.
+ */
+class GrTextureKey {
+public:
+ enum {
+ kHashBits = 7,
+ kHashCount = 1 << kHashBits,
+ kHashMask = kHashCount - 1
+ };
+
+ GrTextureKey(uint32_t p0, uint32_t p1, uint16_t width, uint16_t height) {
+ fP0 = p0;
+ fP1 = p1;
+ fP2 = width | (height << 16);
+ GR_DEBUGCODE(fHashIndex = -1);
+ }
+
+ GrTextureKey(const GrTextureKey& src) {
+ fP0 = src.fP0;
+ fP1 = src.fP1;
+ fP2 = src.fP2;
+ finalize(src.fPrivateBits);
+ }
+
+ //!< returns hash value [0..kHashMask] for the key
+ int hashIndex() const { return fHashIndex; }
+
+ friend bool operator==(const GrTextureKey& a, const GrTextureKey& b) {
+ GR_DEBUGASSERT(-1 != a.fHashIndex && -1 != b.fHashIndex);
+ return a.fP0 == b.fP0 && a.fP1 == b.fP1 && a.fP2 == b.fP2 &&
+ a.fPrivateBits == b.fPrivateBits;
+ }
+
+ friend bool operator!=(const GrTextureKey& a, const GrTextureKey& b) {
+ GR_DEBUGASSERT(-1 != a.fHashIndex && -1 != b.fHashIndex);
+ return !(a == b);
+ }
+
+ friend bool operator<(const GrTextureKey& a, const GrTextureKey& b) {
+ RET_IF_LT_OR_GT(a.fP0, b.fP0);
+ RET_IF_LT_OR_GT(a.fP1, b.fP1);
+ RET_IF_LT_OR_GT(a.fP2, b.fP2);
+ return a.fPrivateBits < b.fPrivateBits;
+ }
+
+private:
+ void finalize(uint32_t privateBits) {
+ fPrivateBits = privateBits;
+ this->computeHashIndex();
+ }
+
+ uint16_t width() const { return fP2 & 0xffff; }
+ uint16_t height() const { return (fP2 >> 16); }
+
+ static uint32_t rol(uint32_t x) {
+ return (x >> 24) | (x << 8);
+ }
+ static uint32_t ror(uint32_t x) {
+ return (x >> 8) | (x << 24);
+ }
+ static uint32_t rohalf(uint32_t x) {
+ return (x >> 16) | (x << 16);
+ }
+
+ void computeHashIndex() {
+ uint32_t hash = fP0 ^ rol(fP1) ^ ror(fP2) ^ rohalf(fPrivateBits);
+ // this way to mix and reduce hash to its index may have to change
+ // depending on how many bits we allocate to the index
+ hash ^= hash >> 16;
+ hash ^= hash >> 8;
+ fHashIndex = hash & kHashMask;
+ }
+
+ uint32_t fP0;
+ uint32_t fP1;
+ uint32_t fP2;
+ uint32_t fPrivateBits;
+
+ // this is computed from the fP... fields
+ int fHashIndex;
+
+ friend class GrContext;
+};
+
+///////////////////////////////////////////////////////////////////////////////
+
+class GrTextureEntry {
+public:
+ GrTexture* texture() const { return fTexture; }
+ const GrTextureKey& key() const { return fKey; }
+
+#if GR_DEBUG
+ GrTextureEntry* next() const { return fNext; }
+ GrTextureEntry* prev() const { return fPrev; }
+#endif
+
+#if GR_DEBUG
+ void validate() const;
+#else
+ void validate() const {}
+#endif
+
+private:
+ GrTextureEntry(const GrTextureKey& key, GrTexture* texture);
+ ~GrTextureEntry();
+
+ bool isLocked() const { return fLockCount != 0; }
+ void lock() { ++fLockCount; }
+ void unlock() {
+ GrAssert(fLockCount > 0);
+ --fLockCount;
+ }
+
+ GrTextureKey fKey;
+ GrTexture* fTexture;
+
+ // track if we're in use, used when we need to purge
+ // we only purge unlocked entries
+ int fLockCount;
+
+ // we're a dlinklist
+ GrTextureEntry* fPrev;
+ GrTextureEntry* fNext;
+
+ friend class GrTextureCache;
+};
+
+///////////////////////////////////////////////////////////////////////////////
+
+#include "GrTHashCache.h"
+
+/**
+ * Cache of GrTexture objects.
+ *
+ * These have a corresponding GrTextureKey, built from 96bits identifying the
+ * texture/bitmap.
+ *
+ * The cache stores the entries in a double-linked list, which is its LRU.
+ * When an entry is "locked" (i.e. given to the caller), it is moved to the
+ * head of the list. If/when we must purge some of the entries, we walk the
+ * list backwards from the tail, since those are the least recently used.
+ *
+ * For fast searches, we maintain a sorted array (based on the GrTextureKey)
+ * which we can bsearch. When a new entry is added, it is inserted into this
+ * array.
+ *
+ * For even faster searches, a hash is computed from the Key. If there is
+ * a collision between two keys with the same hash, we fall back on the
+ * bsearch, and update the hash to reflect the most recent Key requested.
+ */
+class GrTextureCache {
+public:
+ GrTextureCache(int maxCount, size_t maxBytes);
+ ~GrTextureCache(); // uses kFreeTexture_DeleteMode
+
+ /**
+ * Search for an entry with the same Key. If found, "lock" it and return it.
+ * If not found, return null.
+ */
+ GrTextureEntry* findAndLock(const GrTextureKey&);
+
+ /**
+ * Create a new entry, based on the specified key and texture, and return
+ * its "locked" entry.
+ *
+ * Ownership of the texture is transferred to the Entry, which will unref()
+ * it when we are purged or deleted.
+ */
+ GrTextureEntry* createAndLock(const GrTextureKey&, GrTexture*);
+
+ /**
+ * Detach removes an entry from the cache. This prevents the entry from
+ * being found by a subsequent findAndLock() until it is reattached. The
+ * entry still counts against the cache's budget and should be reattached
+ * when exclusive access is no longer needed.
+ */
+ void detach(GrTextureEntry*);
+
+ /**
+ * Reattaches a texture to the cache and unlocks it. Allows it to be found
+ * by a subsequent findAndLock or be purged (provided its lock count is
+ * now 0.)
+ */
+ void reattachAndUnlock(GrTextureEntry*);
+
+ /**
+ * When done with an entry, call unlock(entry) on it, which returns it to
+ * a purgable state.
+ */
+ void unlock(GrTextureEntry*);
+
+ enum DeleteMode {
+ kFreeTexture_DeleteMode,
+ kAbandonTexture_DeleteMode
+ };
+ void deleteAll(DeleteMode);
+
+#if GR_DEBUG
+ void validate() const;
+#else
+ void validate() const {}
+#endif
+
+private:
+ void internalDetach(GrTextureEntry*, bool);
+ void attachToHead(GrTextureEntry*, bool);
+ void purgeAsNeeded(); // uses kFreeTexture_DeleteMode
+
+ class Key;
+ GrTHashTable<GrTextureEntry, Key, 8> fCache;
+
+ // manage the dlink list
+ GrTextureEntry* fHead;
+ GrTextureEntry* fTail;
+
+ // our budget, used in purgeAsNeeded()
+ const int fMaxCount;
+ const size_t fMaxBytes;
+
+ // our current stats, related to our budget
+ int fEntryCount;
+ size_t fEntryBytes;
+ int fClientDetachedCount;
+ size_t fClientDetachedBytes;
+};
+
+///////////////////////////////////////////////////////////////////////////////
+
+#if GR_DEBUG
+ class GrAutoTextureCacheValidate {
+ public:
+ GrAutoTextureCacheValidate(GrTextureCache* cache) : fCache(cache) {
+ cache->validate();
+ }
+ ~GrAutoTextureCacheValidate() {
+ fCache->validate();
+ }
+ private:
+ GrTextureCache* fCache;
+ };
+#else
+ class GrAutoTextureCacheValidate {
+ public:
+ GrAutoTextureCacheValidate(GrTextureCache*) {}
+ };
+#endif
+
+#endif
+
diff --git a/gpu/include/GrTouchGesture.h b/gpu/include/GrTouchGesture.h
new file mode 100644
index 0000000000..03f970b246
--- /dev/null
+++ b/gpu/include/GrTouchGesture.h
@@ -0,0 +1,56 @@
+#ifndef GrTouchGesture_DEFINED
+#define GrTouchGesture_DEFINED
+
+#include "GrTypes.h"
+#include "SkTDArray.h"
+#include "SkMatrix.h"
+
+#include "FlingState.h"
+
+class GrTouchGesture {
+public:
+ GrTouchGesture();
+ ~GrTouchGesture();
+
+ void touchBegin(void* owner, float x, float y);
+ void touchMoved(void* owner, float x, float y);
+ void touchEnd(void* owner);
+ void reset();
+
+ const SkMatrix& localM();
+ const SkMatrix& globalM() const { return fGlobalM; }
+
+private:
+ enum State {
+ kEmpty_State,
+ kTranslate_State,
+ kZoom_State,
+ };
+
+ struct Rec {
+ void* fOwner;
+ float fStartX, fStartY;
+ float fPrevX, fPrevY;
+ float fLastX, fLastY;
+ SkMSec fPrevT, fLastT;
+ };
+ SkTDArray<Rec> fTouches;
+
+ State fState;
+ SkMatrix fLocalM, fGlobalM;
+ FlingState fFlinger;
+ SkMSec fLastUpT;
+ SkPoint fLastUpP;
+
+
+ void flushLocalM();
+ int findRec(void* owner) const;
+ void appendNewRec(void* owner, float x, float y);
+ float computePinch(const Rec&, const Rec&);
+ float limitTotalZoom(float scale) const;
+ bool handleDblTap(float, float);
+};
+
+#endif
+
+
diff --git a/gpu/include/GrTypes.h b/gpu/include/GrTypes.h
new file mode 100644
index 0000000000..a491295192
--- /dev/null
+++ b/gpu/include/GrTypes.h
@@ -0,0 +1,142 @@
+/*
+ Copyright 2010 Google Inc.
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ */
+
+
+#ifndef GrTypes_DEFINED
+#define GrTypes_DEFINED
+
+#include "GrConfig.h"
+
+#include <memory.h>
+#include <string.h>
+
+/**
+ * Macro to round n up to the next multiple of 4, or return it unchanged if
+ * n is already a multiple of 4
+ */
+#define GrALIGN4(n) (((n) + 3) >> 2 << 2)
+#define GrIsALIGN4(n) (((n) & 3) == 0)
+
+template <typename T> const T& GrMin(const T& a, const T& b) {
+ return (a < b) ? a : b;
+}
+
+template <typename T> const T& GrMax(const T& a, const T& b) {
+ return (b < a) ? a : b;
+}
+
+// compile time versions of min/max
+#define GR_CT_MAX(a, b) (((b) < (a)) ? (a) : (b))
+#define GR_CT_MIN(a, b) (((b) < (a)) ? (b) : (a))
+
+/**
+ * divide, rounding up
+ */
+inline uint32_t GrUIDivRoundUp(uint32_t x, uint32_t y) {
+ return (x + (y-1)) / y;
+}
+
+/**
+ * align up
+ */
+inline uint32_t GrUIAlignUp(uint32_t x, uint32_t alignment) {
+ return GrUIDivRoundUp(x, alignment) * alignment;
+}
+
+/**
+ * amount of pad needed to align up
+ */
+inline uint32_t GrUIAlignUpPad(uint32_t x, uint32_t alignment) {
+ return (alignment - x % alignment) % alignment;
+}
+
+/**
+ * align down
+ */
+inline uint32_t GrUIAlignDown(uint32_t x, uint32_t alignment) {
+ return (x / alignment) * alignment;
+}
+
+/**
+ * Count elements in an array
+ */
+#define GR_ARRAY_COUNT(array) (sizeof(array) / sizeof(array[0]))
+
+//!< allocate a block of memory, will never return NULL
+extern void* GrMalloc(size_t bytes);
+
+//!< free block allocated by GrMalloc. ptr may be NULL
+extern void GrFree(void* ptr);
+
+static inline void Gr_bzero(void* dst, size_t size) {
+ memset(dst, 0, size);
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+/**
+ * Return the number of leading zeros in n
+ */
+extern int Gr_clz(uint32_t n);
+
+/**
+ * Return true if n is a power of 2
+ */
+static inline bool GrIsPow2(unsigned n) {
+ return n && 0 == (n & (n - 1));
+}
+
+/**
+ * Return the next power of 2 >= n.
+ */
+static inline uint32_t GrNextPow2(uint32_t n) {
+ return n ? (1 << (32 - Gr_clz(n - 1))) : 1;
+}
+
+///////////////////////////////////////////////////////////////////////////////
+
+/**
+ * 16.16 fixed point type
+ */
+typedef int32_t GrFixed;
+
+#if GR_DEBUG
+
+static inline int16_t GrToS16(intptr_t x) {
+ GrAssert((int16_t)x == x);
+ return (int16_t)x;
+}
+
+#else
+
+#define GrToS16(x) x
+
+#endif
+
+////////////////////////////////////////////////////////////////////////////////
+
+/**
+ * Type used to describe format of vertices in arrays
+ * Values are defined in GrDrawTarget
+ */
+typedef uint16_t GrVertexLayout;
+
+///////////////////////////////////////////////////////////////////////////////
+
+// this is included only to make it easy to use this debugging facility
+#include "GrInstanceCounter.h"
+
+#endif
diff --git a/gpu/include/GrUserConfig.h b/gpu/include/GrUserConfig.h
new file mode 100644
index 0000000000..2e6f3919d6
--- /dev/null
+++ b/gpu/include/GrUserConfig.h
@@ -0,0 +1,57 @@
+#ifndef GrUserConfig_DEFINED
+#define GrUserConfig_DEFINED
+
+#if defined(GR_USER_CONFIG_FILE)
+ #error "default user config pulled in but GR_USER_CONFIG_FILE is defined."
+#endif
+
+#if 0
+ #undef GR_RELEASE
+ #undef GR_DEBUG
+ #define GR_RELEASE 0
+ #define GR_DEBUG 1
+#endif
+
+/*
+ Copyright 2010 Google Inc.
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ */
+
+//#define GR_FORCE_GLCHECKERR 1
+
+/*
+ * The default 32bit pixel config for texture upload is GL_RGBA. If your
+ * bitmaps map to a different GL enum, specify that with this define.
+ */
+//#define SK_GL_32BPP_COLOR_FORMAT GL_RGBA
+
+/*
+ * To diagnose texture cache performance, define this to 1 if you want to see
+ * a log statement everytime we upload an image to create a texture.
+ */
+//#define GR_DUMP_TEXTURE_UPLOAD 1
+
+////////////////////////////////////////////////////////////////////////////////
+// Decide Ganesh types
+
+#define GR_SCALAR_IS_FIXED 0
+#define GR_SCALAR_IS_FLOAT 1
+
+#define GR_TEXT_SCALAR_IS_USHORT 0
+#define GR_TEXT_SCALAR_IS_FIXED 0
+#define GR_TEXT_SCALAR_IS_FLOAT 1
+
+#endif
+
+
diff --git a/gpu/include/GrVertexBuffer.h b/gpu/include/GrVertexBuffer.h
new file mode 100644
index 0000000000..5e83de95d5
--- /dev/null
+++ b/gpu/include/GrVertexBuffer.h
@@ -0,0 +1,92 @@
+/*
+ Copyright 2010 Google Inc.
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ */
+
+
+#ifndef GrVertexBuffer_DEFINED
+#define GrVertexBuffer_DEFINED
+
+#include "GrRefCnt.h"
+
+class GrVertexBuffer : public GrRefCnt {
+protected:
+ GrVertexBuffer(uint32_t sizeInBytes, bool dynamic) :
+ fSizeInBytes(sizeInBytes),
+ fDynamic(dynamic) {}
+public:
+ virtual ~GrVertexBuffer() {}
+
+ /**
+ Retrieves the size of the vertex buffer
+
+ @return the size of the vertex buffer in bytes
+ */
+ uint32_t size() { return fSizeInBytes; }
+
+ /**
+ Retrieves whether the vertex buffer was created with the dynamic flag
+
+ @return true if the vertex buffer was created with the dynamic flag
+ */
+ bool dynamic() const { return fDynamic; }
+
+ /**
+ Indicates that GPU context in which this veretx buffer was created is
+ destroyed and that Ganesh should not attempt to free the texture with the
+ underlying API.
+ */
+ virtual void abandon() = 0;
+
+ /**
+ Locks the vertex buffer to be written by the CPU.
+
+ The previous content of the vertex buffer is invalidated. It is an error to
+ draw whil the buffer is locked. It is an error to call lock on an already
+ locked vertex buffer.
+
+ @return a pointer to the vertex data or NULL if the lock fails.
+ */
+ virtual void* lock() = 0;
+
+ /**
+ Unlocks the vertex buffer.
+
+ The pointer returned by the previous lock call will no longer be valid.
+ */
+ virtual void unlock() = 0;
+
+ /**
+ Queries whether the vertex buffer has been locked.
+
+ @return true if the vertex buffer is locked, false otherwise.
+ */
+ virtual bool isLocked() const = 0;
+
+ /**
+ Updates the vertex buffer data.
+
+ The size of the vertex buffer will be preserved. However, only the updated
+ region will have defined contents.
+
+ @return returns true if the update succeeds, false otherwise.
+ */
+ virtual bool updateData(const void* src, uint32_t srcSizeInBytes) = 0;
+
+private:
+ uint32_t fSizeInBytes;
+ bool fDynamic;
+};
+
+#endif
diff --git a/gpu/include/GrVertexBufferAllocPool.h b/gpu/include/GrVertexBufferAllocPool.h
new file mode 100644
index 0000000000..6a781aa344
--- /dev/null
+++ b/gpu/include/GrVertexBufferAllocPool.h
@@ -0,0 +1,141 @@
+/*
+ Copyright 2010 Google Inc.
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ */
+
+
+#ifndef GrVertexBufferAllocPool_DEFINED
+#define GrVertexBufferAllocPool_DEFINED
+
+#include "GrNoncopyable.h"
+#include "GrTDArray.h"
+#include "GrTArray.h"
+
+class GrVertexBuffer;
+class GrGpu;
+
+/**
+ * A pool of vertices in vertex buffers tied to a GrGpu.
+ *
+ * The pool has an alloc() function that returns a pointer into a locked
+ * vertex buffer. A client can release() if it has over-allocated.
+ *
+ * At creation time a minimum VB size can be specified. Additionally,
+ * a number of vertex buffers to preallocate can be specified. These will
+ * be allocated at the min size and kept until the pool is destroyed.
+ */
+class GrVertexBufferAllocPool : GrNoncopyable {
+public:
+ /**
+ * Constructor
+ *
+ * @param gpu The GrGpu used to create the vertex buffers.
+ * @param bufferSize The size of created VBs (unless an alloc request
+ * exceeds this size in which case a larger VB is
+ * created). This value is clamped to some
+ * reasonable minimum.
+ * @param preallocBufferCnt The pool will allocate this number of VBs at
+ * bufferSize and keep them until it is destroyed.
+ */
+ GrVertexBufferAllocPool(GrGpu* gpu,
+ size_t bufferSize = 0,
+ int preallocBufferCnt = 0);
+ ~GrVertexBufferAllocPool();
+
+ /**
+ * Ensures all VBs are unlocked. Call before using to draw.
+ */
+ void unlock();
+
+ /**
+ * Frees all vertex data that has been allocated with alloc().
+ */
+ void reset();
+
+ /**
+ * Returns a block of memory bytes size big. The vertex buffer
+ * containing the memory is returned in buffer.
+ *
+ * @param layout specifies type of vertices to allocate space for
+ * @param vertexCount number of vertices to allocate space for
+ * @param buffer returns the vertex buffer that will hold the
+ * vertices.
+ * @param startVertex returns the offset into buffer of the first vertex.
+ * In units of the size of a vertex using layout param.
+ * @return pointer to first vertex.
+ */
+ void* alloc(GrVertexLayout layout,
+ uint32_t vertexCount,
+ GrVertexBuffer** buffer,
+ uint32_t* startVertex);
+
+ /**
+ * Gets the number of vertices that can be allocated without changing VBs.
+ * This means either the last VB returned by alloc() if the last alloc did
+ * not exhaust it. If that VB was exhausted by the last alloc or alloc hasn't
+ * been called since reset() then it will be the number of vertices that
+ * would fit in an available preallocated VB. If no preallocated VB
+ * is available then it returns 0 since the next alloc would force a new
+ * VB to be created.
+ */
+ int currentBufferVertices(GrVertexLayout layout) const;
+
+ /**
+ * Gets the number of preallocated buffers that are yet to be used.
+ */
+ int preallocatedBuffersRemaining() const;
+
+ /**
+ * Gets the number of vertices that can fit in a preallocated vertex buffer.
+ * Zero if no preallocated buffers.
+ */
+ int preallocatedBufferVertices(GrVertexLayout layout) const;
+
+ /**
+ * gets the number of preallocated vertex buffers
+ */
+ int preallocatedBufferCount() const;
+
+
+ /**
+ * Releases the most recently allocated bytes back to the pool.
+ */
+ void release(size_t bytes);
+
+ /**
+ * Gets the GrGpu that this pool is associated with.
+ */
+ GrGpu* getGpu() { return fGpu; }
+
+
+private:
+ struct BufferBlock {
+ size_t fBytesFree;
+ GrVertexBuffer* fVertexBuffer;
+ };
+
+ bool createBlock(size_t size);
+ void destroyBlock();
+
+ GrTArray<BufferBlock> fBlocks;
+ GrTDArray<GrVertexBuffer*> fPreallocBuffers;
+ int fPreallocBuffersInUse;
+ int fFirstPreallocBuffer;
+
+ size_t fMinBlockSize;
+ GrGpu* fGpu;
+ void* fBufferPtr;
+};
+
+#endif
diff --git a/gpu/include/SkGpuCanvas.h b/gpu/include/SkGpuCanvas.h
new file mode 100644
index 0000000000..e8e6e7ae10
--- /dev/null
+++ b/gpu/include/SkGpuCanvas.h
@@ -0,0 +1,72 @@
+/*
+ Copyright 2010 Google Inc.
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ */
+
+
+#ifndef SkGpuCanvas_DEFINED
+#define SkGpuCanvas_DEFINED
+
+#include "SkCanvas.h"
+
+class GrContext;
+
+/**
+ * Subclass of canvas that creates devices compatible with the GrContext pass
+ * to the canvas' constructor.
+ */
+class SkGpuCanvas : public SkCanvas {
+public:
+ /**
+ * The GrContext object is reference counted. When passed to our
+ * constructor, its reference count is incremented. In our destructor, the
+ * GrGpu's reference count will be decremented.
+ */
+ explicit SkGpuCanvas(GrContext*);
+ virtual ~SkGpuCanvas();
+
+ /**
+ * Return our GrContext instance
+ */
+ GrContext* context() const { return fContext; }
+
+ /**
+ * Override from SkCanvas. Returns true, and if not-null, sets size to
+ * be the width/height of our viewport.
+ */
+ virtual bool getViewport(SkIPoint* size) const;
+
+ /**
+ * Override from SkCanvas. Returns a new device of the correct subclass,
+ * as determined by the GrGpu passed to our constructor.
+ */
+ virtual SkDevice* createDevice(SkBitmap::Config, int width, int height,
+ bool isOpaque, bool isLayer);
+
+#if 0
+ virtual int saveLayer(const SkRect* bounds, const SkPaint* paint,
+ SaveFlags flags = kARGB_ClipLayer_SaveFlag) {
+ return this->save(flags);
+ }
+#endif
+
+private:
+ GrContext* fContext;
+
+ typedef SkCanvas INHERITED;
+};
+
+#endif
+
+
diff --git a/gpu/include/SkGr.h b/gpu/include/SkGr.h
new file mode 100644
index 0000000000..4e9801f699
--- /dev/null
+++ b/gpu/include/SkGr.h
@@ -0,0 +1,238 @@
+/*
+ Copyright 2010 Google Inc.
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ */
+
+
+#ifndef SkGr_DEFINED
+#define SkGr_DEFINED
+
+#include <stddef.h>
+
+// tetrark headers
+#include "GrConfig.h"
+#include "GrContext.h"
+#include "GrFontScaler.h"
+#include "GrPathIter.h"
+#include "GrClipIterator.h"
+
+// skia headers
+#include "SkBitmap.h"
+#include "SkPath.h"
+#include "SkPoint.h"
+#include "SkRegion.h"
+#include "SkShader.h"
+
+#if (GR_DEBUG && defined(SK_RELEASE)) || (GR_RELEASE && defined(SK_DEBUG))
+// #error "inconsistent GR_DEBUG and SK_DEBUG"
+#endif
+
+#if GR_SCALAR_IS_FIXED
+ #ifdef SK_SCALAR_IS_FIXED
+ #define SK_SCALAR_IS_GR_SCALAR 1
+ #else
+ #define SK_SCALAR_IS_GR_SCALAR 0
+ #endif
+ #define SkScalarToGrScalar(x) SkScalarToFixed(x)
+
+#elif GR_SCALAR_IS_FLOAT
+
+ #ifdef SK_SCALAR_IS_FLOAT
+ #define SK_SCALAR_IS_GR_SCALAR 1
+ #else
+ #define SK_SCALAR_IS_GR_SCALAR 0
+ #endif
+ #define SkScalarToGrScalar(x) SkScalarToFloat(x)
+
+#else
+ #error "Ganesh scalar type not defined"
+#endif
+
+////////////////////////////////////////////////////////////////////////////////
+// Sk to Gr Type conversions
+
+// Verify that SkPoint and GrPoint are compatible if using the same scalar type
+#if 0/*SK_SCALAR_IS_GR_SCALAR*/
+ GR_STATIC_ASSERT(sizeof(SkPoint) == sizeof(GrPoint));
+ GR_STATIC_ASSERT(offsetof(SkPoint,fX) == offsetof(GrPoint,fX)));
+ GR_STATIC_ASSERT(offsetof(SkPoint,fY) == offsetof(GrPoint,fY)));
+#endif
+
+GR_STATIC_ASSERT((int)GrSamplerState::kClamp_WrapMode == (int)SkShader::kClamp_TileMode);
+GR_STATIC_ASSERT((int)GrSamplerState::kRepeat_WrapMode ==(
+ int)SkShader::kRepeat_TileMode);
+GR_STATIC_ASSERT((int)GrSamplerState::kMirror_WrapMode ==
+ (int)SkShader::kMirror_TileMode);
+
+#define sk_tile_mode_to_grwrap(X) ((GrSamplerState::WrapMode)(X))
+
+GR_STATIC_ASSERT((int)GrGpu::kZero_BlendCoeff == (int)SkXfermode::kZero_Coeff);
+GR_STATIC_ASSERT((int)GrGpu::kOne_BlendCoeff == (int)SkXfermode::kOne_Coeff);
+GR_STATIC_ASSERT((int)GrGpu::kSC_BlendCoeff == (int)SkXfermode::kSC_Coeff);
+GR_STATIC_ASSERT((int)GrGpu::kISC_BlendCoeff == (int)SkXfermode::kISC_Coeff);
+GR_STATIC_ASSERT((int)GrGpu::kDC_BlendCoeff == (int)SkXfermode::kDC_Coeff);
+GR_STATIC_ASSERT((int)GrGpu::kIDC_BlendCoeff == (int)SkXfermode::kIDC_Coeff);
+GR_STATIC_ASSERT((int)GrGpu::kSA_BlendCoeff == (int)SkXfermode::kSA_Coeff);
+GR_STATIC_ASSERT((int)GrGpu::kISA_BlendCoeff == (int)SkXfermode::kISA_Coeff);
+GR_STATIC_ASSERT((int)GrGpu::kDA_BlendCoeff == (int)SkXfermode::kDA_Coeff);
+GR_STATIC_ASSERT((int)GrGpu::kIDA_BlendCoeff == (int)SkXfermode::kIDA_Coeff);
+
+#define sk_blend_to_grblend(X) ((GrGpu::BlendCoeff)(X))
+
+GR_STATIC_ASSERT((int)SkPath::kMove_Verb == (int)GrPathIter::kMove_Command);
+GR_STATIC_ASSERT((int)SkPath::kLine_Verb == (int)GrPathIter::kLine_Command);
+GR_STATIC_ASSERT((int)SkPath::kQuad_Verb == (int)GrPathIter::kQuadratic_Command);
+GR_STATIC_ASSERT((int)SkPath::kCubic_Verb == (int)GrPathIter::kCubic_Command);
+GR_STATIC_ASSERT((int)SkPath::kClose_Verb == (int)GrPathIter::kClose_Command);
+GR_STATIC_ASSERT((int)SkPath::kDone_Verb == (int)GrPathIter::kEnd_Command);
+
+#define sk_path_verb_to_gr_path_command(X) ((GrPathIter::Command)(X))
+
+///////////////////////////////////////////////////////////////////////////////
+
+#include "SkColorPriv.h"
+
+static inline GrRect Sk2Gr(const SkRect& src) {
+ return GrRect(SkScalarToGrScalar(src.fLeft),
+ SkScalarToGrScalar(src.fTop),
+ SkScalarToGrScalar(src.fRight),
+ SkScalarToGrScalar(src.fBottom));
+}
+
+class SkGr {
+public:
+ static inline SkIRect& SetIRect(SkIRect* dst, const GrIRect& src) {
+ GR_STATIC_ASSERT(sizeof(*dst) == sizeof(src));
+ memcpy(dst, &src, sizeof(*dst));
+ return *dst;
+ }
+
+ static inline GrIRect& SetIRect(GrIRect* dst, const SkIRect& src) {
+ GR_STATIC_ASSERT(sizeof(*dst) == sizeof(src));
+ memcpy(dst, &src, sizeof(*dst));
+ return *dst;
+ }
+
+ /**
+ * Convert the SkBitmap::Config to the corresponding PixelConfig, or
+ * kUnknown_PixelConfig if the conversion cannot be done.
+ */
+ static GrTexture::PixelConfig BitmapConfig2PixelConfig(SkBitmap::Config,
+ bool isOpaque);
+
+ static GrTexture::PixelConfig Bitmap2PixelConfig(const SkBitmap& bm) {
+ return BitmapConfig2PixelConfig(bm.config(), bm.isOpaque());
+ }
+
+ static void SkMatrix2GrMatrix(const SkMatrix& m, GrMatrix* g) {
+ g->setAll(SkScalarToGrScalar(m[0]),
+ SkScalarToGrScalar(m[1]),
+ SkScalarToGrScalar(m[2]),
+ SkScalarToGrScalar(m[3]),
+ SkScalarToGrScalar(m[4]),
+ SkScalarToGrScalar(m[5]),
+ SkScalarToGrScalar(m[6]),
+ SkScalarToGrScalar(m[7]),
+ SkScalarToGrScalar(m[8]));
+ }
+
+ static GrColor SkColor2GrColor(SkColor c) {
+ SkPMColor pm = SkPreMultiplyColor(c);
+ unsigned r = SkGetPackedR32(pm);
+ unsigned g = SkGetPackedG32(pm);
+ unsigned b = SkGetPackedB32(pm);
+ unsigned a = SkGetPackedA32(pm);
+ return GrColorPackRGBA(r, g, b, a);
+ }
+
+ /**
+ * This abandons all texture caches (for bitmaps and text) associated with
+ * the gpu, and frees any associated skia caches. It differs from
+ * deleteAllTextures in that it assumes that the gpu has lots its context,
+ * and thus the associated HW textures are no longer valid
+ */
+ static void AbandonAllTextures(GrContext*);
+};
+
+////////////////////////////////////////////////////////////////////////////////
+// Classes
+
+class SkGrPathIter : public GrPathIter {
+public:
+ SkGrPathIter(const SkPath& path) : fIter(path, false), fPath(path) {}
+ virtual Command next(GrPoint pts[]);
+ virtual Command next();
+ virtual void rewind();
+ virtual ConvexHint hint() const;
+private:
+
+#if !SK_SCALAR_IS_GR_SCALAR
+ SkPoint fPoints[4];
+#endif
+ SkPath::Iter fIter;
+ const SkPath& fPath;
+};
+
+class SkGrClipIterator : public GrClipIterator {
+public:
+ void reset(const SkRegion& clip) {
+ fIter.reset(clip);
+ this->invalidateBoundsCache();
+ }
+
+ // overrides
+
+ virtual bool isDone() { return fIter.done(); }
+ virtual void getRect(GrIRect* rect) {
+ SkGr::SetIRect(rect, fIter.rect());
+ }
+ virtual void next() { fIter.next(); }
+ virtual void rewind() { fIter.rewind(); }
+ virtual void computeBounds(GrIRect* bounds);
+
+private:
+ SkRegion::Iterator fIter;
+};
+
+class SkGlyphCache;
+
+class SkGrFontScaler : public GrFontScaler {
+public:
+ explicit SkGrFontScaler(SkGlyphCache* strike);
+ virtual ~SkGrFontScaler();
+
+ // overrides
+ virtual const GrKey* getKey();
+ virtual bool getPackedGlyphBounds(GrGlyph::PackedID, GrIRect* bounds);
+ virtual bool getPackedGlyphImage(GrGlyph::PackedID, int width, int height,
+ int rowBytes, void* image);
+ virtual bool getGlyphPath(uint16_t glyphID, GrPath*);
+
+private:
+ SkGlyphCache* fStrike;
+ GrKey* fKey;
+// DECLARE_INSTANCE_COUNTER(SkGrFontScaler);
+};
+
+////////////////////////////////////////////////////////////////////////////////
+// Helper functions
+
+GrTextureEntry* sk_gr_create_bitmap_texture(GrContext* ctx,
+ GrTextureKey* key,
+ const GrSamplerState& sampler,
+ const SkBitmap& bitmap);
+
+void sk_gr_set_paint(GrContext* ctx, const SkPaint& paint, bool justAlpha = false);
+
+#endif
diff --git a/gpu/include/SkGrTexturePixelRef.h b/gpu/include/SkGrTexturePixelRef.h
new file mode 100644
index 0000000000..1f5133f86d
--- /dev/null
+++ b/gpu/include/SkGrTexturePixelRef.h
@@ -0,0 +1,50 @@
+/*
+ Copyright 2010 Google Inc.
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+ */
+
+
+#ifndef SkGrTexturePixelRef_DEFINED
+#define SkGrTexturePixelRef_DEFINED
+
+#include "SkPixelRef.h"
+#include "GrGpu.h"
+
+class SkGrTexturePixelRef : public SkPixelRef {
+public:
+ SkGrTexturePixelRef(GrTexture*);
+ virtual ~SkGrTexturePixelRef();
+
+ // override from SkPixelRef
+ virtual SkGpuTexture* getTexture() { return (SkGpuTexture*)fTexture; }
+
+protected:
+ // override from SkPixelRef
+ virtual void* onLockPixels(SkColorTable** ptr) {
+ if (ptr) {
+ *ptr = NULL;
+ }
+ return NULL;
+ }
+
+ // override from SkPixelRef
+ virtual void onUnlockPixels() {}
+
+private:
+ GrTexture* fTexture;
+ typedef SkPixelRef INHERITED;
+};
+
+#endif
+
diff --git a/gpu/include/SkUIView.h b/gpu/include/SkUIView.h
new file mode 100644
index 0000000000..5e12e004d6
--- /dev/null
+++ b/gpu/include/SkUIView.h
@@ -0,0 +1,64 @@
+#import <UIKit/UIKit.h>
+
+#include "SkMatrix.h"
+#include "FlingState.h"
+
+#import <OpenGLES/EAGL.h>
+#import <OpenGLES/ES1/gl.h>
+#import <OpenGLES/ES1/glext.h>
+
+class SkOSWindow;
+class SkEvent;
+
+@interface SkUIView : UIView <UIAccelerometerDelegate> {
+ BOOL fRedrawRequestPending;
+ SkOSWindow* fWind;
+ SkMatrix fMatrix, fLocalMatrix;
+ bool fNeedGestureEnded;
+
+ SkMatrix fRotateMatrix;
+
+ float fFirstPinchX, fFirstPinchY;
+ bool fNeedFirstPinch;
+
+ float fZoomAroundX, fZoomAroundY;
+ bool fZoomAround;
+
+ FlingState fFlingState;
+
+ GrAnimateFloat fWarpState;
+ bool fUseWarp;
+
+ struct {
+ EAGLContext* fContext;
+ GLuint fRenderbuffer;
+ GLuint fStencilbuffer;
+ GLuint fFramebuffer;
+ GLint fWidth;
+ GLint fHeight;
+ } fGL;
+
+ UILabel* fTitleLabel;
+
+ enum Backend {
+ kGL_Backend,
+ kRaster_Backend,
+ };
+
+ // these are visible to DetailViewController
+ Backend fBackend;
+ bool fComplexClip;
+}
+
+@property (nonatomic, assign) SkOSWindow *fWind;
+@property (nonatomic, retain) UILabel* fTitleLabel;
+@property (nonatomic, assign) Backend fBackend;
+@property (nonatomic, assign) bool fComplexClip;
+@property (nonatomic, assign, setter=setWarpState) bool fUseWarp;
+
+- (void)setSkTitle:(const char*)title;
+- (void)postInvalWithRect:(const SkIRect*)rectOrNil;
+- (BOOL)onHandleEvent:(const SkEvent&)event;
+
+@end
+