Commit 35e2e62b authored by Derek Sollenberger's avatar Derek Sollenberger
Browse files

Skia Merge (revision 1327)

Change-Id: I46f41274d07a3d7bac4728f8841c7f5e89dc9181
parent f1735072
......@@ -114,6 +114,7 @@ LOCAL_SRC_FILES:= \
src/core/SkBlitter_RGB16.cpp \
src/core/SkBlitter_Sprite.cpp \
src/core/SkCanvas.cpp \
src/core/SkClampRange.cpp \
src/core/SkClipStack.cpp \
src/core/SkColor.cpp \
src/core/SkColorFilter.cpp \
......@@ -140,7 +141,7 @@ LOCAL_SRC_FILES:= \
src/core/SkMath.cpp \
src/core/SkMatrix.cpp \
src/core/SkMemory_stdlib.cpp \
src/core/SkMetaData.cpp \
src/core/SkMetaData.cpp \
src/core/SkPackBits.cpp \
src/core/SkPaint.cpp \
src/core/SkPath.cpp \
......@@ -173,6 +174,7 @@ LOCAL_SRC_FILES:= \
src/core/SkStrokerPriv.cpp \
src/core/SkTSearch.cpp \
src/core/SkTypeface.cpp \
src/core/SkTypefaceCache.cpp \
src/core/SkUnPreMultiply.cpp \
src/core/SkXfermode.cpp \
src/core/SkWriter32.cpp \
......@@ -181,6 +183,7 @@ LOCAL_SRC_FILES:= \
src/utils/SkDumpCanvas.cpp \
src/utils/SkInterpolator.cpp \
src/utils/SkLayer.cpp \
src/utils/SkOSFile.cpp \
src/utils/SkMeshUtils.cpp \
src/utils/SkNinePatch.cpp \
src/utils/SkParse.cpp \
......@@ -189,9 +192,18 @@ LOCAL_SRC_FILES:= \
src/utils/SkUnitMappers.cpp
ifeq ($(TARGET_ARCH),arm)
ifeq ($(ARCH_ARM_HAVE_NEON),true)
LOCAL_SRC_FILES += \
src/opts/memset16_neon.S \
src/opts/memset32_neon.S
endif
LOCAL_SRC_FILES += \
src/opts/SkBlitRow_opts_arm.cpp \
src/opts/SkBitmapProcState_opts_arm.cpp
src/opts/SkBitmapProcState_opts_arm.cpp \
src/opts/opts_check_arm.cpp \
src/opts/memset.arm.S
else
LOCAL_SRC_FILES += \
src/opts/SkBlitRow_opts_none.cpp \
......@@ -270,7 +282,6 @@ LOCAL_SRC_FILES:= \
gpu/src/GrGLTexture.cpp \
gpu/src/GrGLVertexBuffer.cpp \
gpu/src/GrGpu.cpp \
gpu/src/GrGpuGLShaders2.cpp \
gpu/src/GrGpuGLFixed.cpp \
gpu/src/GrGpuFactory.cpp \
gpu/src/GrGLUtil.cpp \
......
......@@ -33,10 +33,12 @@ protected:
}
virtual void onDraw(SkCanvas* canvas) {
for (int i = 0; i < N; i++) {
SkBitmap bm;
SkImageDecoder::DecodeFile(fFilename, &bm, fPrefConfig,
SkImageDecoder::kDecodePixels_Mode);
if (fFilename) {
for (int i = 0; i < N; i++) {
SkBitmap bm;
SkImageDecoder::DecodeFile(fFilename, &bm, fPrefConfig,
SkImageDecoder::kDecodePixels_Mode);
}
}
}
......
#include "SkBenchmark.h"
#include "SkBitmap.h"
#include "SkCanvas.h"
#include "SkColorPriv.h"
#include "SkGradientShader.h"
#include "SkPaint.h"
#include "SkShader.h"
#include "SkString.h"
#include "SkUnitMapper.h"
struct GradData {
int fCount;
const SkColor* fColors;
const SkScalar* fPos;
};
static const SkColor gColors[] = {
SK_ColorRED, SK_ColorGREEN, SK_ColorBLUE, SK_ColorWHITE, SK_ColorBLACK
};
static const SkScalar gPos0[] = { 0, SK_Scalar1 };
static const SkScalar gPos1[] = { SK_Scalar1/4, SK_Scalar1*3/4 };
static const SkScalar gPos2[] = {
0, SK_Scalar1/8, SK_Scalar1/2, SK_Scalar1*7/8, SK_Scalar1
};
static const GradData gGradData[] = {
{ 2, gColors, NULL },
{ 2, gColors, gPos0 },
{ 2, gColors, gPos1 },
{ 5, gColors, NULL },
{ 5, gColors, gPos2 }
};
static SkShader* MakeLinear(const SkPoint pts[2], const GradData& data,
SkShader::TileMode tm, SkUnitMapper* mapper) {
return SkGradientShader::CreateLinear(pts, data.fColors, data.fPos,
data.fCount, tm, mapper);
}
static SkShader* MakeRadial(const SkPoint pts[2], const GradData& data,
SkShader::TileMode tm, SkUnitMapper* mapper) {
SkPoint center;
center.set(SkScalarAve(pts[0].fX, pts[1].fX),
SkScalarAve(pts[0].fY, pts[1].fY));
return SkGradientShader::CreateRadial(center, center.fX, data.fColors,
data.fPos, data.fCount, tm, mapper);
}
static SkShader* MakeSweep(const SkPoint pts[2], const GradData& data,
SkShader::TileMode tm, SkUnitMapper* mapper) {
SkPoint center;
center.set(SkScalarAve(pts[0].fX, pts[1].fX),
SkScalarAve(pts[0].fY, pts[1].fY));
return SkGradientShader::CreateSweep(center.fX, center.fY, data.fColors,
data.fPos, data.fCount, mapper);
}
static SkShader* Make2Radial(const SkPoint pts[2], const GradData& data,
SkShader::TileMode tm, SkUnitMapper* mapper) {
SkPoint center0, center1;
center0.set(SkScalarAve(pts[0].fX, pts[1].fX),
SkScalarAve(pts[0].fY, pts[1].fY));
center1.set(SkScalarInterp(pts[0].fX, pts[1].fX, SkIntToScalar(3)/5),
SkScalarInterp(pts[0].fY, pts[1].fY, SkIntToScalar(1)/4));
return SkGradientShader::CreateTwoPointRadial(
center1, (pts[1].fX - pts[0].fX) / 7,
center0, (pts[1].fX - pts[0].fX) / 2,
data.fColors, data.fPos, data.fCount, tm, mapper);
}
typedef SkShader* (*GradMaker)(const SkPoint pts[2], const GradData& data,
SkShader::TileMode tm, SkUnitMapper* mapper);
static const struct {
GradMaker fMaker;
const char* fName;
int fRepeat;
} gGrads[] = {
{ MakeLinear, "linear", 15 },
{ MakeRadial, "radial1", 10 },
{ MakeSweep, "sweep", 1 },
{ Make2Radial, "radial2", 5 },
};
enum GradType { // these must match the order in gGrads
kLinear_GradType,
kRadial_GradType,
kSweep_GradType,
kRadial2_GradType
};
///////////////////////////////////////////////////////////////////////////////
class GradientBench : public SkBenchmark {
SkString fName;
SkShader* fShader;
int fCount;
enum {
W = 400,
H = 400,
N = 1
};
public:
GradientBench(void* param, GradType gt) : INHERITED(param) {
fName.printf("gradient_%s", gGrads[gt].fName);
const SkPoint pts[2] = {
{ 0, 0 },
{ SkIntToScalar(W), SkIntToScalar(H) }
};
fCount = N * gGrads[gt].fRepeat;
fShader = gGrads[gt].fMaker(pts, gGradData[0],
SkShader::kClamp_TileMode, NULL);
}
virtual ~GradientBench() {
fShader->unref();
}
protected:
virtual const char* onGetName() {
return fName.c_str();
}
virtual void onDraw(SkCanvas* canvas) {
SkPaint paint;
this->setupPaint(&paint);
paint.setShader(fShader);
SkRect r = { 0, 0, SkIntToScalar(W), SkIntToScalar(H) };
for (int i = 0; i < fCount; i++) {
canvas->drawRect(r, paint);
}
}
private:
typedef SkBenchmark INHERITED;
};
static SkBenchmark* Fact0(void* p) { return new GradientBench(p, kLinear_GradType); }
static SkBenchmark* Fact1(void* p) { return new GradientBench(p, kRadial_GradType); }
static SkBenchmark* Fact2(void* p) { return new GradientBench(p, kSweep_GradType); }
static SkBenchmark* Fact3(void* p) { return new GradientBench(p, kRadial2_GradType); }
static BenchRegistry gReg0(Fact0);
static BenchRegistry gReg1(Fact1);
static BenchRegistry gReg2(Fact2);
static BenchRegistry gReg3(Fact3);
This diff is collapsed.
......@@ -5,7 +5,7 @@
namespace skiagm {
static void make_bitmaps(int w, int h, SkBitmap* src, SkBitmap* dst) {
static void make_bitmaps(int w, int h, SkBitmap* src, SkBitmap* dst) {
src->setConfig(SkBitmap::kARGB_8888_Config, w, h);
src->allocPixels();
src->eraseColor(0);
......@@ -17,10 +17,10 @@ static void make_bitmaps(int w, int h, SkBitmap* src, SkBitmap* dst) {
SkScalar hh = SkIntToScalar(h);
p.setAntiAlias(true);
p.setColor(0xFFFFCC44);
p.setColor(0xFFFFCC44);
r.set(0, 0, ww*3/4, hh*3/4);
c.drawOval(r, p);
dst->setConfig(SkBitmap::kARGB_8888_Config, w, h);
dst->allocPixels();
dst->eraseColor(0);
......@@ -40,42 +40,46 @@ class XfermodesGM : public GM {
void draw_mode(SkCanvas* canvas, SkXfermode* mode, int alpha,
SkScalar x, SkScalar y) {
SkPaint p;
canvas->drawBitmap(fSrcB, x, y, &p);
canvas->drawBitmap(fSrcB, x, y, &p);
p.setAlpha(alpha);
p.setXfermode(mode);
canvas->drawBitmap(fDstB, x, y, &p);
}
public:
const static int W = 64;
const static int H = 64;
XfermodesGM() {
fBG.setConfig(SkBitmap::kARGB_4444_Config, 2, 2, 4);
fBG.setPixels(gBG);
fBG.setIsOpaque(true);
XfermodesGM() {
// Do all this work in a temporary so we get a deep copy,
// especially of gBG.
SkBitmap scratchBitmap;
scratchBitmap.setConfig(SkBitmap::kARGB_4444_Config, 2, 2, 4);
scratchBitmap.setPixels(gBG);
scratchBitmap.setIsOpaque(true);
scratchBitmap.copyTo(&fBG, SkBitmap::kARGB_4444_Config);
make_bitmaps(W, H, &fSrcB, &fDstB);
}
protected:
virtual SkString onShortName() {
return SkString("xfermodes");
}
virtual SkISize onISize() {
virtual SkISize onISize() {
return make_isize(790, 640);
}
void drawBG(SkCanvas* canvas) {
canvas->drawColor(SK_ColorWHITE);
}
virtual void onDraw(SkCanvas* canvas) {
canvas->translate(SkIntToScalar(10), SkIntToScalar(20));
this->drawBG(canvas);
const struct {
SkXfermode::Mode fMode;
const char* fLabel;
......@@ -92,7 +96,7 @@ protected:
{ SkXfermode::kSrcATop_Mode, "SrcATop" },
{ SkXfermode::kDstATop_Mode, "DstATop" },
{ SkXfermode::kXor_Mode, "Xor" },
{ SkXfermode::kPlus_Mode, "Plus" },
{ SkXfermode::kMultiply_Mode, "Multiply" },
{ SkXfermode::kScreen_Mode, "Screen" },
......@@ -106,7 +110,7 @@ protected:
{ SkXfermode::kDifference_Mode, "Difference" },
{ SkXfermode::kExclusion_Mode, "Exclusion" },
};
const SkScalar w = SkIntToScalar(W);
const SkScalar h = SkIntToScalar(H);
SkShader* s = SkShader::CreateBitmapShader(fBG,
......@@ -115,13 +119,13 @@ protected:
SkMatrix m;
m.setScale(SkIntToScalar(6), SkIntToScalar(6));
s->setLocalMatrix(m);
SkPaint labelP;
labelP.setAntiAlias(true);
labelP.setTextAlign(SkPaint::kCenter_Align);
const int W = 5;
SkScalar x0 = 0;
for (int twice = 0; twice < 2; twice++) {
SkScalar x = x0, y = 0;
......@@ -130,22 +134,21 @@ protected:
SkAutoUnref aur(mode);
SkRect r;
r.set(x, y, x+w, y+h);
SkPaint p;
p.setStyle(SkPaint::kFill_Style);
p.setShader(s);
canvas->drawRect(r, p);
canvas->saveLayer(&r, NULL, SkCanvas::kARGB_ClipLayer_SaveFlag);
// canvas->save();
draw_mode(canvas, mode, twice ? 0x88 : 0xFF, r.fLeft, r.fTop);
canvas->restore();
r.inset(-SK_ScalarHalf, -SK_ScalarHalf);
p.setStyle(SkPaint::kStroke_Style);
p.setShader(NULL);
canvas->drawRect(r, p);
#if 1
canvas->drawText(gModes[i].fLabel, strlen(gModes[i].fLabel),
x + w/2, y - labelP.getTextSize()/2, labelP);
......@@ -171,4 +174,3 @@ static GM* MyFactory(void*) { return new XfermodesGM; }
static GMRegistry reg(MyFactory);
}
......@@ -56,4 +56,3 @@ private:
#endif
......@@ -36,12 +36,13 @@ public:
* Must be at least itemSize*itemsPerBlock sized.
* Caller is responsible for freeing this memory.
*/
GrAllocator(size_t itemSize, uint32_t itemsPerBlock, void* initialBlock) :
GrAllocator(size_t itemSize, int itemsPerBlock, void* initialBlock) :
fBlocks(fBlockInitialStorage, NUM_INIT_BLOCK_PTRS),
fItemSize(itemSize),
fItemsPerBlock(itemsPerBlock),
fOwnFirstBlock(NULL == initialBlock),
fCount(0) {
GrAssert(itemsPerBlock > 0);
fBlockSize = fItemSize * fItemsPerBlock;
fBlocks.push_back() = initialBlock;
GR_DEBUGCODE(if (!fOwnFirstBlock) {*((char*)initialBlock+fBlockSize-1)='a';} );
......@@ -53,7 +54,7 @@ public:
* @return pointer to the added item.
*/
void* push_back() {
uint32_t indexInBlock = fCount % fItemsPerBlock;
int indexInBlock = fCount % fItemsPerBlock;
// we always have at least one block
if (0 == indexInBlock) {
if (0 != fCount) {
......@@ -72,9 +73,9 @@ public:
* removes all added items
*/
void reset() {
uint32_t blockCount = GrMax((unsigned)1,
GrUIDivRoundUp(fCount, fItemsPerBlock));
for (uint32_t i = 1; i < blockCount; ++i) {
int blockCount = GrMax((unsigned)1,
GrUIDivRoundUp(fCount, fItemsPerBlock));
for (int i = 1; i < blockCount; ++i) {
GrFree(fBlocks[i]);
}
if (fOwnFirstBlock) {
......@@ -88,7 +89,7 @@ public:
/**
* count of items
*/
uint32_t count() const {
int count() const {
return fCount;
}
......@@ -116,8 +117,8 @@ public:
/**
* access item by index.
*/
void* operator[] (uint32_t i) {
GrAssert(i < fCount);
void* operator[] (int i) {
GrAssert(i >= 0 && i < fCount);
return (char*)fBlocks[i / fItemsPerBlock] +
fItemSize * (i % fItemsPerBlock);
}
......@@ -125,22 +126,22 @@ public:
/**
* access item by index.
*/
const void* operator[] (uint32_t i) const {
GrAssert(i < fCount);
const void* operator[] (int i) const {
GrAssert(i >= 0 && i < fCount);
return (const char*)fBlocks[i / fItemsPerBlock] +
fItemSize * (i % fItemsPerBlock);
}
private:
static const uint32_t NUM_INIT_BLOCK_PTRS = 8;
static const int NUM_INIT_BLOCK_PTRS = 8;
GrTArray<void*> fBlocks;
size_t fBlockSize;
char fBlockInitialStorage[NUM_INIT_BLOCK_PTRS*sizeof(void*)];
size_t fBlockSize;
char fBlockInitialStorage[NUM_INIT_BLOCK_PTRS*sizeof(void*)];
size_t fItemSize;
uint32_t fItemsPerBlock;
int fItemsPerBlock;
bool fOwnFirstBlock;
uint32_t fCount;
int fCount;
};
template <typename T>
......@@ -150,7 +151,7 @@ private:
public:
virtual ~GrTAllocator() {};
/**
* Create an allocator
*
......@@ -159,9 +160,18 @@ public:
* 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)
{}
GrTAllocator(int itemsPerBlock, void* initialBlock)
: fAllocator(sizeof(T), itemsPerBlock, initialBlock) {}
/**
* Create an allocator using a GrAlignedTAlloc as the initial block.
*
* @param initialBlock specifies the storage for the initial block
* and the size of subsequent blocks.
*/
template <int N>
GrTAllocator(GrAlignedSTStorage<N,T>* initialBlock)
: fAllocator(sizeof(T), N, initialBlock->get()) {}
/**
* Adds an item and returns it.
......@@ -179,8 +189,8 @@ public:
* removes all added items
*/
void reset() {
uint32_t c = fAllocator.count();
for (uint32_t i = 0; i < c; ++i) {
int c = fAllocator.count();
for (int i = 0; i < c; ++i) {
((T*)fAllocator[i])->~T();
}
fAllocator.reset();
......@@ -189,7 +199,7 @@ public:
/**
* count of items
*/
uint32_t count() const {
int count() const {
return fAllocator.count();
}
......@@ -215,14 +225,14 @@ public:
/**
* access item by index.
*/
T& operator[] (uint32_t i) {
T& operator[] (int i) {
return *(T*)(fAllocator[i]);
}
/**
* access item by index.
*/
const T& operator[] (uint32_t i) const {
const T& operator[] (int i) const {
return *(const T*)(fAllocator[i]);
}
};
......
......@@ -22,6 +22,7 @@
#include "GrRect.h"
#include "GrPath.h"
#include "GrTArray.h"
#include "GrTemplates.h"
class GrClip {
......@@ -140,7 +141,7 @@ private:
enum {
kPreAllocElements = 4,
};
uint8_t fListMemory[sizeof(Element) * kPreAllocElements];
GrAlignedSTStorage<kPreAllocElements, Element> fListStorage;
GrTArray<Element> fList;
};
#endif
......
......@@ -120,6 +120,8 @@ typedef short int16_t;
typedef unsigned short uint16_t;
typedef int int32_t;
typedef unsigned uint32_t;
typedef __int64 int64_t;
typedef unsigned __int64 uint64_t;
#else
/*
* Include stdint.h with defines that trigger declaration of C99 limit/const
......@@ -169,11 +171,15 @@ typedef unsigned uint32_t;
#define GR_DLL 0
#endif
#if GR_WIN32_BUILD && GR_DLL
#if GR_IMPLEMENTATION
#define GR_API __declspec(dllexport)
#if GR_DLL
#if GR_WIN32_BUILD
#if GR_IMPLEMENTATION
#define GR_API __declspec(dllexport)
#else
#define GR_API __declspec(dllimport)
#endif
#else
#define GR_API __declspec(dllimport)
#define GR_API __attribute__((visibility("default")))
#endif
#else
#define GR_API
......@@ -328,10 +334,6 @@ inline void GrCrash(const char* msg) { GrPrintf(msg); GrAlwaysAssert(false); }
#define GR_DUMP_TEXTURE_UPLOAD 0
#endif
#ifndef GR_USE_NEW_GLSHADERS
#define GR_USE_NEW_GLSHADERS 0
#endif
/**
* GR_COLLECT_STATS controls whether the GrGpu class collects stats.
* If not already defined then collect in debug build but not release.
......
......@@ -18,12 +18,13 @@
#define GrContext_DEFINED
#include "GrClip.h"
#include "GrGpu.h"
#include "GrTextureCache.h"
#include "GrPaint.h"
#include "GrPathRenderer.h"
class GrFontCache;
class GrGpu;
struct GrGpuStats;
class GrPathIter;
class GrVertexBufferAllocPool;
class GrIndexBufferAllocPool;
......@@ -34,8 +35,8 @@ public:
/**
* Creates a GrContext from within a 3D context.
*/
static GrContext* Create(GrGpu::Engine engine,
GrGpu::Platform3DContext context3D);
static GrContext* Create(GrEngine engine,
GrPlatform3DContext context3D);
/**
* Helper to create a opengl-shader based context
......@@ -91,35 +92,34 @@ public:
*/
GrTextureEntry* createAndLockTexture(GrTextureKey* key,
const GrSamplerState&,
const GrGpu::TextureDesc&,
const GrTextureDesc&,
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.
* Returns a texture matching the desc. It's contents are unknown. Subsequent
* requests with the same descriptor are not guaranteed to return the same
* texture. The same texture is guaranteed not be returned again until it is
* unlocked.
*
* Textures created by createAndLockTexture() hide the complications of
* tiling non-power-of-two textures on APIs that don't support this (e.g.
* unextended GLES2). Tiling a npot texture created by lockKeylessTexture on
* such an API will create gaps in the tiling pattern. This includes clamp
* mode. (This may be addressed in a future update.)
*/
void detachCachedTexture(GrTextureEntry*);
GrTextureEntry* lockKeylessTexture(const GrTextureDesc& desc);
/**
* 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.)
* When done with an entry, call unlockTexture(entry) on it, which returns
* it to the cache, where it may be purged.
*/
void reattachAndUnlockCachedTexture(GrTextureEntry*);
void unlockTexture(GrTextureEntry* entry);
/**
* Creates a texture that is outside the cache. Does not count against
* cache's budget.
*/
GrTexture* createUncachedTexture(const GrGpu::TextureDesc&,
GrTexture* createUncachedTexture(const GrTextureDesc&,
void* srcData,
size_t rowBytes);
......@@ -209,14 +209,7 @@ public:
GrRenderTarget* createPlatformRenderTarget(intptr_t platformRenderTarget,
int stencilBits,
bool isMultisampled,
int width, int height) {
#if GR_DEBUG
GrPrintf("Using deprecated createPlatformRenderTarget API.");
#endif
return fGpu->createPlatformRenderTarget(platformRenderTarget,
stencilBits, isMultisampled,
width, height);
}
int width, int height);
/**
* DEPRECATED, WILL BE REMOVED SOON. USE createPlatformSurface.
......@@ -229,12 +222,7 @@ public:
*
* @return the newly created GrRenderTarget
*/
GrRenderTarget* createRenderTargetFrom3DApiState() {
#if GR_DEBUG
GrPrintf("Using deprecated createRenderTargetFrom3DApiState API.");
#endif
return fGpu->createRenderTargetFrom3DApiState();
}
GrRenderTarget* createRenderTargetFrom3DApiState();
///////////////////////////////////////////////////////////////////////////
// Matrix state
......@@ -265,7 +253,7 @@ public:
* Gets the current clip.
* @return the current clip.
*/
const GrClip& getClip() const { return fGpu->getClip(); }
const GrClip& getClip() const;
/**
* Sets the clip.
......@@ -283,9 +271,11 @@ public:
// Draws
/**
* Erase the entire render target, ignoring any clips
* Clear the entire or rect of the render target, ignoring any clips.
* @param rect the rect to clear or the whole thing if rect is NULL.
* @param color the color to clear to.
*/
void eraseColor(GrColor color);
void clear(const GrIRect* rect, GrColor color);
/**
* Draw everywhere (respecting the clip) with the paint.
......@@ -506,16 +496,6 @@ public:
void writePixels(int left, int top, int width, int height,
GrPixelConfig, const void* buffer, size_t stride);
///////////////////////////////////////////////////////////////////////////
// Statistics
void resetStats();
const GrGpu::Stats& getStats() const;
void printStats() const;
///////////////////////////////////////////////////////////////////////////
// Helpers
......@@ -547,6 +527,9 @@ public:
GrDrawTarget* getTextTarget(const GrPaint& paint);
void flushText();
const GrIndexBuffer* getQuadIndexBuffer() const;
void resetStats();
const GrGpuStats& getStats() const;
void printStats() const;
private:
// used to keep track of when we need to flush the draw buffer
......@@ -568,15 +551,35 @@ private:
GrIndexBufferAllocPool* fDrawBufferIBAllocPool;
GrInOrderDrawBuffer* fDrawBuffer;
GrIndexBuffer* fAAFillRectIndexBuffer;
GrIndexBuffer* fAAStrokeRectIndexBuffer;
GrContext(GrGpu* gpu);
void fillAARect(GrDrawTarget* target,
const GrPaint& paint,
const GrRect& devRect);
void strokeAARect(GrDrawTarget* target,
const GrPaint& paint,
const GrRect& devRect,
const GrVec& devStrokeSize);
inline int aaFillRectIndexCount() const;
GrIndexBuffer* aaFillRectIndexBuffer();
inline int aaStrokeRectIndexCount() const;
GrIndexBuffer* aaStrokeRectIndexBuffer();
void setupDrawBuffer();
void flushDrawBuffer();
static void SetPaint(const GrPaint& paint, GrDrawTarget* target);
bool finalizeTextureKey(GrTextureKey*, const GrSamplerState&) const;
bool finalizeTextureKey(GrTextureKey*,
const GrSamplerState&,
bool keyless) const;
GrDrawTarget* prepareToDraw(const GrPaint& paint, DrawCategory drawType);
......@@ -586,6 +589,30 @@ private:
GrPathIter* path,
GrPathFill fill);
struct OffscreenRecord;
// we currently only expose stage 0 through the paint so use stage 1. We
// use stage 1 for the offscreen.
enum {
kOffscreenStage = 1,
};
bool doOffscreenAA(GrDrawTarget* target,
const GrPaint& paint,
bool isLines) const;
// sets up target to draw coverage to the supersampled render target
bool setupOffscreenAAPass1(GrDrawTarget* target,
bool requireStencil,
const GrIRect& boundRect,
OffscreenRecord* record);
// sets up target to sample coverage of supersampled render target back
// to the main render target using stage kOffscreenStage.
void offscreenAAPass2(GrDrawTarget* target,
const GrPaint& paint,
const GrIRect& boundRect,
OffscreenRecord* record);
};
/**
......@@ -612,3 +639,4 @@ private:
#endif
#include "GrContext_impl.h"
......@@ -17,6 +17,20 @@
#ifndef GrContext_impl_DEFINED
#define GrContext_impl_DEFINED
struct GrContext::OffscreenRecord {
OffscreenRecord() { fEntry0 = NULL; fEntry1 = NULL; }
~OffscreenRecord() { GrAssert(NULL == fEntry0 && NULL == fEntry1); }
enum Downsample {
k4x4TwoPass_Downsample,
k4x4SinglePass_Downsample,
kFSAA_Downsample
} fDownsample;
GrTextureEntry* fEntry0;
GrTextureEntry* fEntry1;
GrDrawTarget::SavedDrawState fSavedState;
};
template <typename POS_SRC, typename TEX_SRC,
typename COL_SRC, typename IDX_SRC>
inline void GrContext::drawCustomVertices(const GrPaint& paint,
......@@ -76,11 +90,31 @@ inline void GrContext::drawCustomVertices(const GrPaint& paint,
idxSrc->writeValue(i, indices + i);
}
bool doAA = false;
OffscreenRecord record;
GrIRect bounds;
if (-1 == texOffsets[0] && -1 == colorOffset &&
this->doOffscreenAA(target, paint, GrIsPrimTypeLines(primitiveType))) {
GrRect b;
b.setBounds(geo.positions(), vertexCount);
target->getViewMatrix().mapRect(&b);
b.roundOut(&bounds);
if (this->setupOffscreenAAPass1(target, false, bounds, &record)) {
doAA = true;
}
}
if (NULL == idxSrc) {
target->drawNonIndexed(primitiveType, 0, vertexCount);
} else {
target->drawIndexed(primitiveType, 0, 0, vertexCount, indexCount);
}
if (doAA) {
geo.set(NULL, 0, 0, 0); // have to release geom before can draw again
this->offscreenAAPass2(target, paint, bounds, &record);
}
}
class GrNullTexCoordSource {
......
......@@ -26,6 +26,8 @@
#include "GrTexture.h"
#include "GrStencil.h"
#include "SkXfermode.h"
class GrTexture;
class GrClipIterator;
class GrVertexBuffer;
......@@ -64,18 +66,22 @@ public:
* default to disabled.
*/
enum StateBits {
kDither_StateBit = 0x1,//<! Perform color dithering
kAntialias_StateBit = 0x2,//<! Perform anti-aliasing. The render-
kDither_StateBit = 0x01, //<! Perform color dithering
kAntialias_StateBit = 0x02, //<! 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
kClip_StateBit = 0x04, //<! Controls whether drawing is clipped
// against the region specified by
// setClip.
kNoColorWrites_StateBit = 0x8,//<! If set it disables writing colors.
// Useful while performing stencil ops.
kNoColorWrites_StateBit = 0x08, //<! If set it disables writing colors.
// Useful while performing stencil
// ops.
kEdgeAA_StateBit = 0x10, //<! Perform edge anti-aliasing.
// Requires the edges to be passed in
// setEdgeAAData().
// subclass may use additional bits internally
kDummyStateBit,
......@@ -131,6 +137,9 @@ protected:
// all DrState members should default to something
// valid by the memset
memset(this, 0, sizeof(DrState));
// This is an exception to our memset, since it will
// result in no change.
fColorFilterXfermode = SkXfermode::kDstIn_Mode;
GrAssert((intptr_t)(void*)NULL == 0LL);
GrAssert(fStencilSettings.isDisabled());
}
......@@ -144,9 +153,12 @@ protected:
GrRenderTarget* fRenderTarget;
GrColor fColor;
DrawFace fDrawFace;
GrColor fColorFilterColor;
SkXfermode::Mode fColorFilterXfermode;
GrStencilSettings fStencilSettings;
GrMatrix fViewMatrix;
float fEdgeAAEdges[18];
bool operator ==(const DrState& s) const {
return 0 == memcmp(this, &s, sizeof(DrState));
}
......@@ -275,6 +287,18 @@ public:
*/
void preConcatViewMatrix(const GrMatrix& m);
/**
* Multiplies the current view matrix by a matrix
*
* After this call V' = m*V 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 view matrix.
*/
void postConcatViewMatrix(const GrMatrix& m);
/**
* Retrieves the current view matrix
* @return the current view matrix.
......@@ -299,6 +323,11 @@ public:
*/
void setColor(GrColor);
/**
* Add a color filter that can be represented by a color and a mode.
*/
void setColorFilter(GrColor, SkXfermode::Mode);
/**
* Sets the color to be used for the next draw to be
* (r,g,b,a) = (alpha, alpha, alpha, alpha).
......@@ -338,6 +367,10 @@ public:
return 0 != (fCurrDrawState.fFlagBits & kDither_StateBit);
}
bool isAntialiasState() const {
return 0 != (fCurrDrawState.fFlagBits & kAntialias_StateBit);
}
bool isClipState() const {
return 0 != (fCurrDrawState.fFlagBits & kClip_StateBit);
}
......@@ -459,6 +492,14 @@ public:
*/
bool canDisableBlend() const;
/**
* Sets the edge data required for edge antialiasing.
*
* @param edges 3 * 6 float values, representing the edge
* equations in Ax + By + C form
*/
void setEdgeAAData(const float edges[18]);
private:
static const int TEX_COORD_BIT_CNT = kNumStages*kMaxTexCoords;
public:
......@@ -498,7 +539,7 @@ public:
kHighVertexLayoutBit = kDummyVertexLayoutBit - 1
};
// make sure we haven't exceeded the number of bits in GrVertexLayout.
GR_STATIC_ASSERT(kHighVertexLayoutBit < (1 << 8*sizeof(GrVertexLayout)));
GR_STATIC_ASSERT(kHighVertexLayoutBit < ((uint64_t)1 << 8*sizeof(GrVertexLayout)));
/**
* There are three paths for specifying geometry (vertices and optionally
......@@ -539,7 +580,7 @@ public:
* 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
* if indexCount is nonzero, *indices will be the array of indices
* to be filled by caller. The next indexed draw will read from
* these indices.
*
......@@ -718,13 +759,28 @@ public:
drawRect(rect, matrix, stageEnableBitfield, NULL, NULL);
}
/**
* Clear the render target. Ignores the clip and all other draw state
* (blend mode, stages, etc). Clears the whole thing if rect is NULL,
* otherwise just the rect.
*/
virtual void clear(const GrIRect* rect, GrColor color) = 0;
///////////////////////////////////////////////////////////////////////////
class AutoStateRestore : ::GrNoncopyable {
public:
AutoStateRestore();
AutoStateRestore(GrDrawTarget* target);
~AutoStateRestore();
/**
* if this object is already saving state for param target then
* this does nothing. Otherise, it restores previously saved state on
* previous target (if any) and saves current state on param target.
*/
void set(GrDrawTarget* target);
private:
GrDrawTarget* fDrawTarget;
SavedDrawState fDrawState;
......@@ -771,20 +827,16 @@ public:
GrVertexLayout vertexLayout,
uint32_t vertexCount,
uint32_t indexCount) {
fTarget = target;
fSuccess = fTarget->reserveAndLockGeometry(vertexLayout,
vertexCount,
indexCount,
&fVertices,
&fIndices);
fTarget = NULL;
this->set(target, vertexLayout, vertexCount, indexCount);
}
AutoReleaseGeometry() {
fSuccess = false;
fTarget = NULL;
}
~AutoReleaseGeometry() {
if (fSuccess) {
if (NULL != fTarget) {
fTarget->releaseReservedGeometry();
}
}
......@@ -793,19 +845,23 @@ public:
GrVertexLayout vertexLayout,
uint32_t vertexCount,
uint32_t indexCount) {
if (fSuccess) {
if (NULL != fTarget) {
fTarget->releaseReservedGeometry();
}
fTarget = target;
fSuccess = fTarget->reserveAndLockGeometry(vertexLayout,
vertexCount,
indexCount,
&fVertices,
&fIndices);
return fSuccess;
if (NULL != fTarget) {
if (!fTarget->reserveAndLockGeometry(vertexLayout,
vertexCount,
indexCount,
&fVertices,
&fIndices)) {
fTarget = NULL;
}
}
return NULL != fTarget;
}
bool succeeded() const { return fSuccess; }
bool succeeded() const { return NULL != fTarget; }
void* vertices() const { return fVertices; }
void* indices() const { return fIndices; }
......@@ -815,7 +871,6 @@ public:
private:
GrDrawTarget* fTarget;
bool fSuccess;
void* fVertices;
void* fIndices;
};
......@@ -994,6 +1049,15 @@ public:
static void VertexLayoutUnitTest();
protected:
// given a vertex layout and a draw state, will a stage be used?
static bool StageWillBeUsed(int stage, GrVertexLayout layout,
const DrState& state) {
return NULL != state.fTextures[stage] && VertexUsesStage(stage, layout);
}
bool isStageEnabled(int stage) const {
return StageWillBeUsed(stage, fGeometrySrc.fVertexLayout, fCurrDrawState);
}
// Helpers for GrDrawTarget subclasses that won't have private access to
// SavedDrawState but need to peek at the state values.
......
......@@ -53,23 +53,46 @@
*
* GR_GL_CHECK_ERROR_START: controls the initial value of gCheckErrorGL
* when GR_GL_CHECK_ERROR is 1. Defaults to 1.
*
* GR_GL_NO_CONSTANT_ATTRIBUTES: if this evaluates to true then the GL backend
* will use uniforms instead of attributes in all cases when there is not
* per-vertex data. This is important when the underlying GL implementation
* doesn't actually support immediate style attribute values (e.g. when
* the GL stream is converted to DX as in ANGLE on Chrome). Defaults to 0.
*
* GR_GL_ATTRIBUTE_MATRICES: If changing uniforms is very expensive it may be
* faster to use vertex attributes for matrices (set via glVertexAttrib3fv).
* Setting this build flag enables this behavior. GR_GL_NO_CONSTANT_ATTRIBUTES
* must not be set since this uses constant attributes for the matrices.
* Defaults to 0.
*/
#if !defined(GR_GL_LOG_CALLS)
#define GR_GL_LOG_CALLS 0
#define GR_GL_LOG_CALLS 0
#endif
#if !defined(GR_GL_LOG_CALLS_START)
#define GR_GL_LOG_CALLS_START 0
#define GR_GL_LOG_CALLS_START 0
#endif
#if !defined(GR_GL_CHECK_ERROR)
#define GR_GL_CHECK_ERROR GR_DEBUG
#define GR_GL_CHECK_ERROR GR_DEBUG
#endif
#if !defined(GR_GL_CHECK_ERROR_START)
#define GR_GL_CHECK_ERROR_START 1
#define GR_GL_CHECK_ERROR_START 1
#endif
#if !defined(GR_GL_NO_CONSTANT_ATTRIBUTES)
#define GR_GL_NO_CONSTANT_ATTRIBUTES 0
#endif
#if !defined(GR_GL_ATTRIBUTE_MATRICES)
#define GR_GL_ATTRIBUTE_MATRICES 0
#endif
#if(GR_GL_NO_CONSTANT_ATTRIBUTES) && (GR_GL_ATTRIBUTE_MATRICES)
#error "Cannot combine GR_GL_NO_CONSTANT_ATTRIBUTES and GR_GL_ATTRIBUTE_MATRICES"
#endif
////////////////////////////////////////////////////////////////////////////////
......@@ -110,7 +133,7 @@
// Pick a pixel config for 32bit bitmaps. Our default is GL_RGBA (except on
// Windows where we match GDI's order).
#ifndef GR_GL_32BPP_COLOR_FORMAT
#if GR_WIN32_BUILD
#if GR_WIN32_BUILD || GR_LINUX_BUILD
#define GR_GL_32BPP_COLOR_FORMAT GR_GL_BGRA
#else
#define GR_GL_32BPP_COLOR_FORMAT GR_GL_RGBA
......@@ -138,7 +161,7 @@ extern void GrGLClearErr();
#endif
#define GR_GL(X) GrGLGetGLInterface()->f##X;; GR_GL_LOG_CALLS_IMPL(X); GR_GL_CHECK_ERROR_IMPL(X);
#define GR_GL_NO_ERR(X) GrGLGetGLInterface()->f##X;; GR_GL_LOG_CALLS_IMPL(X); GR_GL_CHECK_ERROR_IMPL(X);
#define GR_GL_NO_ERR(X) GrGLGetGLInterface()->f##X;; GR_GL_LOG_CALLS_IMPL(X);
#define GR_GL_SUPPORT_DESKTOP (kDesktop_GrGLBinding == GrGLGetGLInterface()->fBindingsExported)
#define GR_GL_SUPPORT_ES1 (kES1_GrGLBinding == GrGLGetGLInterface()->fBindingsExported)
......
......@@ -2,9 +2,12 @@
#define GrGLConfig_chrome_DEFINED
// chrome always assumes BGRA
#define GR_GL_32BPP_COLOR_FORMAT GR_GL_BGRA
#define GR_GL_32BPP_COLOR_FORMAT GR_GL_BGRA
// glGetError() forces a sync with gpu process on chrome
#define GR_GL_CHECK_ERROR_START 0
#define GR_GL_CHECK_ERROR_START 0
// ANGLE creates a temp VB for vertex attributes not specified per-vertex.
#define GR_GL_NO_CONSTANT_ATTRIBUTES GR_WIN32_BUILD
#endif
......@@ -19,6 +19,7 @@
#define GrGLInterface_DEFINED
#include "GrGLConfig.h"
#include "GrTypes.h"
#if !defined(GR_GL_FUNCTION_TYPE)
#define GR_GL_FUNCTION_TYPE
......@@ -83,16 +84,6 @@ enum GrGLBinding {
};
extern "C" {
/*
* The following interface exports the OpenGL entry points used by the system.
* Use of OpenGL calls is disallowed. All calls should be invoked through
* the global instance of this struct, defined above.
*
* IMPORTANT NOTE: The OpenGL entry points exposed here include both core GL
* functions, and extensions. The system assumes that the address of the
* extension pointer will be valid across contexts.
*/
struct GrGLInterface {
typedef GrGLvoid (GR_GL_FUNCTION_TYPE *GrGLActiveTextureProc)(GrGLenum texture);
typedef GrGLvoid (GR_GL_FUNCTION_TYPE *GrGLAttachShaderProc)(GrGLuint program, GrGLuint shader);
typedef GrGLvoid (GR_GL_FUNCTION_TYPE *GrGLBindAttribLocationProc)(GrGLuint program, GrGLuint index, const char* name);
......@@ -160,10 +151,25 @@ struct GrGLInterface {
typedef GrGLvoid (GR_GL_FUNCTION_TYPE *GrGLTexImage2DProc)(GrGLenum target, GrGLint level, GrGLint internalformat, GrGLsizei width, GrGLsizei height, GrGLint border, GrGLenum format, GrGLenum type, const GrGLvoid* pixels);
typedef GrGLvoid (GR_GL_FUNCTION_TYPE *GrGLTexParameteriProc)(GrGLenum target, GrGLenum pname, GrGLint param);
typedef GrGLvoid (GR_GL_FUNCTION_TYPE *GrGLTexSubImage2DProc)(GrGLenum target, GrGLint level, GrGLint xoffset, GrGLint yoffset, GrGLsizei width, GrGLsizei height, GrGLenum format, GrGLenum type, const GrGLvoid* pixels);
typedef GrGLvoid (GR_GL_FUNCTION_TYPE *GrGLUniform1fProc)(GrGLint location, GrGLfloat v0);
typedef GrGLvoid (GR_GL_FUNCTION_TYPE *GrGLUniform1iProc)(GrGLint location, GrGLint v0);
typedef GrGLvoid (GR_GL_FUNCTION_TYPE *GrGLUniform1fvProc)(GrGLint location, GrGLsizei count, const GrGLfloat* v);
typedef GrGLvoid (GR_GL_FUNCTION_TYPE *GrGLUniform1iProc)(GrGLint location, GrGLint x);
typedef GrGLvoid (GR_GL_FUNCTION_TYPE *GrGLUniform1ivProc)(GrGLint location, GrGLsizei count, const GrGLint* v);
typedef GrGLvoid (GR_GL_FUNCTION_TYPE *GrGLUniform2fProc)(GrGLint location, GrGLfloat v0, GrGLfloat v1);
typedef GrGLvoid (GR_GL_FUNCTION_TYPE *GrGLUniform2iProc)(GrGLint location, GrGLint v0, GrGLint v1);
typedef GrGLvoid (GR_GL_FUNCTION_TYPE *GrGLUniform2fvProc)(GrGLint location, GrGLsizei count, const GrGLfloat* v);
typedef GrGLvoid (GR_GL_FUNCTION_TYPE *GrGLUniform2ivProc)(GrGLint location, GrGLsizei count, const GrGLint* v);
typedef GrGLvoid (GR_GL_FUNCTION_TYPE *GrGLUniform3fProc)(GrGLint location, GrGLfloat v0, GrGLfloat v1, GrGLfloat v2);
typedef GrGLvoid (GR_GL_FUNCTION_TYPE *GrGLUniform3iProc)(GrGLint location, GrGLint v0, GrGLint v1, GrGLint v2);
typedef GrGLvoid (GR_GL_FUNCTION_TYPE *GrGLUniform3fvProc)(GrGLint location, GrGLsizei count, const GrGLfloat* v);
typedef GrGLvoid (GR_GL_FUNCTION_TYPE *GrGLUniform3ivProc)(GrGLint location, GrGLsizei count, const GrGLint* v);
typedef GrGLvoid (GR_GL_FUNCTION_TYPE *GrGLUniform4fProc)(GrGLint location, GrGLfloat v0, GrGLfloat v1, GrGLfloat v2, GrGLfloat v3);
typedef GrGLvoid (GR_GL_FUNCTION_TYPE *GrGLUniform4iProc)(GrGLint location, GrGLint v0, GrGLint v1, GrGLint v2, GrGLint v3);
typedef GrGLvoid (GR_GL_FUNCTION_TYPE *GrGLUniform4fvProc)(GrGLint location, GrGLsizei count, const GrGLfloat* v);
typedef GrGLvoid (GR_GL_FUNCTION_TYPE *GrGLUniform4ivProc)(GrGLint location, GrGLsizei count, const GrGLint* v);
typedef GrGLvoid (GR_GL_FUNCTION_TYPE *GrGLUniformMatrix2fvProc)(GrGLint location, GrGLsizei count, GrGLboolean transpose, const GrGLfloat* value);
typedef GrGLvoid (GR_GL_FUNCTION_TYPE *GrGLUniformMatrix3fvProc)(GrGLint location, GrGLsizei count, GrGLboolean transpose, const GrGLfloat* value);
typedef GrGLvoid (GR_GL_FUNCTION_TYPE *GrGLUniformMatrix4fvProc)(GrGLint location, GrGLsizei count, GrGLboolean transpose, const GrGLfloat* value);
typedef GrGLvoid (GR_GL_FUNCTION_TYPE *GrGLUseProgramProc)(GrGLuint program);
typedef GrGLvoid (GR_GL_FUNCTION_TYPE *GrGLVertexAttrib4fvProc)(GrGLuint indx, const GrGLfloat* values);
typedef GrGLvoid (GR_GL_FUNCTION_TYPE *GrGLVertexAttribPointerProc)(GrGLuint indx, GrGLint size, GrGLenum type, GrGLboolean normalized, GrGLsizei stride, const GrGLvoid* ptr);
......@@ -193,6 +199,19 @@ struct GrGLInterface {
// Buffer mapping (extension in ES).
typedef GrGLvoid* (GR_GL_FUNCTION_TYPE *GrGLMapBufferProc)(GrGLenum target, GrGLenum access);
typedef GrGLboolean (GR_GL_FUNCTION_TYPE *GrGLUnmapBufferProc)(GrGLenum target);
} // extern "C"
/*
* The following interface exports the OpenGL entry points used by the system.
* Use of OpenGL calls is disallowed. All calls should be invoked through
* the global instance of this struct, defined above.
*
* IMPORTANT NOTE: The OpenGL entry points exposed here include both core GL
* functions, and extensions. The system assumes that the address of the
* extension pointer will be valid across contexts.
*/
struct GrGLInterface {
bool validate(GrEngine engine) const;
// Indicator variable specifying the type of GL implementation
// exported: GLES{1|2} or Desktop.
......@@ -265,10 +284,25 @@ struct GrGLInterface {
GrGLTexImage2DProc fTexImage2D;
GrGLTexParameteriProc fTexParameteri;
GrGLTexSubImage2DProc fTexSubImage2D;
GrGLUniform1fvProc fUniform1fv;
GrGLUniform1fProc fUniform1f;
GrGLUniform1iProc fUniform1i;
GrGLUniform1fvProc fUniform1fv;
GrGLUniform1ivProc fUniform1iv;
GrGLUniform2fProc fUniform2f;
GrGLUniform2iProc fUniform2i;
GrGLUniform2fvProc fUniform2fv;
GrGLUniform2ivProc fUniform2iv;
GrGLUniform3fProc fUniform3f;
GrGLUniform3iProc fUniform3i;
GrGLUniform3fvProc fUniform3fv;
GrGLUniform3ivProc fUniform3iv;
GrGLUniform4fProc fUniform4f;
GrGLUniform4iProc fUniform4i;
GrGLUniform4fvProc fUniform4fv;
GrGLUniform4ivProc fUniform4iv;
GrGLUniformMatrix2fvProc fUniformMatrix2fv;
GrGLUniformMatrix3fvProc fUniformMatrix3fv;
GrGLUniformMatrix4fvProc fUniformMatrix4fv;
GrGLUseProgramProc fUseProgram;
GrGLVertexAttrib4fvProc fVertexAttrib4fv;
GrGLVertexAttribPointerProc fVertexAttribPointer;
......@@ -303,8 +337,10 @@ struct GrGLInterface {
// make this the last entry in the static initializer. It can help to guard
// against failing to initialize newly-added members of this struct.
enum { kStaticInitEndGuard } fStaticInitEndGuard;
};
} // extern "C"
private:
bool validateShaderFunctions() const;
bool validateFixedFunctions() const;
};
#endif
......@@ -28,116 +28,43 @@ class GrIndexBufferAllocPool;
class GrResource;
class GrVertexBufferAllocPool;
/**
* Gpu usage statistics.
*/
struct GrGpuStats {
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;
};
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);
/**
* 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().
kNoStencil_TextureFlag = 0x2, //<! If the texture is used as a
// rendertarget but a stencil
// buffer is not required. Stencil
// may be required for clipping and
// path rendering.
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
GrPixelConfig 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;
};
static GrGpu* Create(GrEngine, GrPlatform3DContext context3D);
////////////////////////////////////////////////////////////////////////////
......@@ -180,7 +107,7 @@ public:
*
* @return The texture object if successful, otherwise NULL.
*/
GrTexture* createTexture(const TextureDesc& desc,
GrTexture* createTexture(const GrTextureDesc& desc,
const void* srcData, size_t rowBytes);
/**
* Wraps an externally-created rendertarget in a GrRenderTarget.
......@@ -234,13 +161,6 @@ public:
*/
GrIndexBuffer* createIndexBuffer(uint32_t size, bool dynamic);
/**
* Erase the entire render target, ignoring any clips/scissors.
*
* This is issued to the GPU driver immediately.
*/
void eraseColor(GrColor color);
/**
* Are 8 bit paletted textures supported.
*
......@@ -272,6 +192,17 @@ public:
*/
bool supportsBufferLocking() const { return fBufferLockSupport; }
/**
* Does the 3D API support anti-aliased lines. If so then line primitive
* types will use this functionality when the AA state flag is set.
*/
bool supportsAALines() const { return fAALineSupport; }
/**
* Does the subclass support GrSamplerState::k4x4Downsample_Filter
*/
bool supports4x4DownsampleFilter() const { return f4X4DownsampleFilterSupport; }
/**
* 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
......@@ -285,6 +216,11 @@ public:
* value.
*/
int minRenderTargetHeight() const { return fMinRenderTargetHeight; }
/**
* Reports whether full scene anti-aliasing is supported.
*/
bool supportsFullsceneAA() const { return fFSAASupport; }
/**
* Returns true if NPOT textures can be created
......@@ -319,6 +255,7 @@ public:
virtual void drawNonIndexed(GrPrimitiveType type,
int startVertex,
int vertexCount);
virtual void clear(const GrIRect* rect, GrColor color);
/**
* Installs a path renderer that will be used to draw paths that are
......@@ -370,7 +307,7 @@ public:
int left, int top, int width, int height,
GrPixelConfig config, void* buffer);
const Stats& getStats() const;
const GrGpuStats& getStats() const;
void resetStats();
void printStats() const;
......@@ -445,6 +382,9 @@ protected:
bool fNPOTRenderTargetSupport;
bool fTwoSidedStencilSupport;
bool fStencilWrapOpsSupport;
bool fAALineSupport;
bool fFSAASupport;
bool f4X4DownsampleFilterSupport; // supports GrSamplerState::k4x4Downsample_Filter
// set by subclass to true if index and vertex buffers can be locked, false
// otherwise.
......@@ -455,7 +395,7 @@ protected:
int fMinRenderTargetHeight;
int fMaxTextureDimension;
Stats fStats;
GrGpuStats fStats;
const GrVertexBuffer* fCurrPoolVertexBuffer;
int fCurrPoolStartVertex;
......@@ -483,7 +423,7 @@ protected:
virtual void resetContext() = 0;
// overridden by API-specific derived class to create objects.
virtual GrTexture* onCreateTexture(const TextureDesc& desc,
virtual GrTexture* onCreateTexture(const GrTextureDesc& desc,
const void* srcData,
size_t rowBytes) = 0;
virtual GrResource* onCreatePlatformSurface(const GrPlatformSurfaceDesc& desc) = 0;
......@@ -498,8 +438,9 @@ protected:
virtual GrIndexBuffer* onCreateIndexBuffer(uint32_t size,
bool dynamic) = 0;
// overridden by API-specific derivated class to perform the erase.
virtual void onEraseColor(GrColor color) = 0;
// overridden by API-specific derivated class to perform the clear and
// clearRect. NULL rect means clear whole target.
virtual void onClear(const GrIRect* rect, GrColor color) = 0;
// overridden by API-specific derived class to perform the draw call.
virtual void onDrawIndexed(GrPrimitiveType type,
......@@ -539,7 +480,7 @@ protected:
virtual void flushScissor(const GrIRect* rect) = 0;
// GrGpu subclass removes the clip from the stencil buffer
virtual void eraseStencilClip(const GrIRect& rect) = 0;
virtual void clearStencilClip(const GrIRect& rect) = 0;
private:
GrContext* fContext; // not reffed (context refs gpu)
......
......@@ -100,6 +100,8 @@ public:
int* vertexCount,
int* indexCount) const;
virtual void clear(const GrIRect* rect, GrColor color);
private:
struct Draw {
......@@ -115,6 +117,12 @@ private:
const GrIndexBuffer* fIndexBuffer;
};
struct Clear {
int fBeforeDrawIdx;
GrIRect fRect;
GrColor fColor;
};
virtual bool onAcquireGeometry(GrVertexLayout vertexLayout,
void** vertices,
void** indices);
......@@ -135,6 +143,7 @@ private:
GrTAllocator<Draw> fDraws;
GrTAllocator<SavedDrawState> fStates;
GrTAllocator<Clear> fClears;
GrTAllocator<GrClip> fClips;
bool fClipSet;
......@@ -158,18 +167,19 @@ private:
size_t fReservedIndexBytes;
size_t fUsedReservedVertexBytes;
size_t fUsedReservedIndexBytes;
enum {
kDrawPreallocCnt = 8,
kStatePreallocCnt = 8,
kClipPreallocCnt = 8,
kClearPreallocCnt = 4,
};
GrAlignedSTStorage<kDrawPreallocCnt, Draw> fDrawStorage;
GrAlignedSTStorage<kStatePreallocCnt, SavedDrawState> fStateStorage;
GrAlignedSTStorage<kClipPreallocCnt, GrClip> fClipStorage;
GrAlignedSTStorage<kClearPreallocCnt, Clear> fClearStorage;
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];
typedef GrDrawTarget INHERITED;
};
......
......@@ -18,383 +18,9 @@
#ifndef GrMatrix_DEFINED
#define GrMatrix_DEFINED
#include "GrPoint.h"
#include "GrRect.h"
#include "SkMatrix.h"
struct GrRect;
/*
* 3x3 matrix
*/
class GrMatrix {
public:
static const GrMatrix& I() {
static const GrMatrix I = GrMatrix(GR_Scalar1, 0, 0,
0, GR_Scalar1, 0,
0, 0, gRESCALE);
return I;
};
static const GrMatrix& InvalidMatrix() {
static const GrMatrix INV =
GrMatrix(GR_ScalarMax, GR_ScalarMax, GR_ScalarMax,
GR_ScalarMax, GR_ScalarMax, GR_ScalarMax,
GR_ScalarMax, GR_ScalarMax, GR_ScalarMax);
return INV;
}
/**
* 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(const 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(const GrScalar values[]) {
for (int i = 0; i < 9; ++i) {
fM[i] = values[i];
}
this->computeTypeMask();
}
/**
* 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;
this->computeTypeMask();
}
/**
* 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:
static const GrScalar gRESCALE;
void computeTypeMask() {
fTypeMask = 0;
if (0 != fM[kPersp0] || 0 != fM[kPersp1] || gRESCALE != fM[kPersp2]) {
fTypeMask |= kPerspective_TypeBit;
}
if (GR_Scalar1 != fM[kScaleX] || GR_Scalar1 != fM[kScaleY]) {
fTypeMask |= kScale_TypeBit;
if (0 == fM[kScaleX] && 0 == fM[kScaleY]) {
fTypeMask |= kZeroScale_TypeBit;
}
}
if (0 != fM[kSkewX] || 0 != fM[kSkewY]) {
fTypeMask |= kSkew_TypeBit;
}
if (0 != fM[kTransX] || 0 != fM[kTransY]) {
fTypeMask |= kTranslate_TypeBit;
}
}
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;
}
}
}
typedef SkMatrix GrMatrix;
#endif
......@@ -21,6 +21,8 @@
#include "GrColor.h"
#include "GrSamplerState.h"
#include "SkXfermode.h"
/**
* The paint describes how pixels are colored when the context draws to
* them.
......@@ -38,6 +40,9 @@ public:
GrSamplerState fSampler;
GrColor fColorFilterColor;
SkXfermode::Mode fColorFilterXfermode;
void setTexture(GrTexture* texture) {
GrSafeRef(texture);
GrSafeUnref(fTexture);
......@@ -59,6 +64,9 @@ public:
fColor = paint.fColor;
fColorFilterColor = paint.fColorFilterColor;
fColorFilterXfermode = paint.fColorFilterXfermode;
fSampler = paint.fSampler;
fTexture = paint.fTexture;
GrSafeRef(fTexture);
......@@ -74,6 +82,12 @@ public:
resetOptions();
resetColor();
resetTexture();
resetColorFilter();
}
void resetColorFilter() {
fColorFilterXfermode = SkXfermode::kDst_Mode;
fColorFilterColor = GrColorPackRGBA(0xff, 0xff, 0xff, 0xff);
}
private:
......
......@@ -22,6 +22,7 @@
#include "GrPathIter.h"
#include "GrTDArray.h"
#include "GrPoint.h"
#include "GrRect.h"
class GrPath : public GrPathSink {
public:
......@@ -33,6 +34,8 @@ public:
GrConvexHint getConvexHint() const { return fConvexHint; }
void setConvexHint(GrConvexHint hint) { fConvexHint = hint; }
const GrRect& getConservativeBounds() const { return fConservativeBounds; }
void resetFromIter(GrPathIter*);
bool operator ==(const GrPath& path) const;
......@@ -66,6 +69,7 @@ public:
virtual GrConvexHint convexHint() const;
virtual GrPathCmd next();
virtual void rewind();
virtual bool getConservativeBounds(GrRect* rect) const;
/**
* Sets iterator to begining of path
......@@ -84,7 +88,8 @@ private:
GrTDArray<GrPathCmd> fCmds;
GrTDArray<GrPoint> fPts;
GrConvexHint fConvexHint;
GrConvexHint fConvexHint;
GrRect fConservativeBounds;
// this ensures we have a moveTo at the start of each contour
inline void ensureMoveTo();
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment