diff options
Diffstat (limited to 'gpu/src/GrContext.cpp')
-rw-r--r-- | gpu/src/GrContext.cpp | 1525 |
1 files changed, 0 insertions, 1525 deletions
diff --git a/gpu/src/GrContext.cpp b/gpu/src/GrContext.cpp deleted file mode 100644 index 4ebf225..0000000 --- a/gpu/src/GrContext.cpp +++ /dev/null @@ -1,1525 +0,0 @@ -/* - Copyright 2011 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. - */ - -#include "GrContext.h" -#include "GrGpu.h" -#include "GrTextureCache.h" -#include "GrTextStrike.h" -#include "GrMemory.h" -#include "GrClipIterator.h" -#include "GrIndexBuffer.h" -#include "GrInOrderDrawBuffer.h" -#include "GrBufferAllocPool.h" -#include "GrPathRenderer.h" - -// larger than this, and we don't AA. set to 0 for no AA -#ifndef GR_MAX_OFFSCREEN_AA_DIM - #define GR_MAX_OFFSCREEN_AA_DIM 0 -#endif - -#define DEFER_TEXT_RENDERING 1 - -#define BATCH_RECT_TO_RECT (1 && !GR_STATIC_RECT_VB) - -static const size_t MAX_TEXTURE_CACHE_COUNT = 128; -static const size_t MAX_TEXTURE_CACHE_BYTES = 8 * 1024 * 1024; - -static const size_t DRAW_BUFFER_VBPOOL_BUFFER_SIZE = 1 << 18; -static const int DRAW_BUFFER_VBPOOL_PREALLOC_BUFFERS = 4; - -// We are currently only batching Text and drawRectToRect, both -// of which use the quad index buffer. -static const size_t DRAW_BUFFER_IBPOOL_BUFFER_SIZE = 0; -static const int DRAW_BUFFER_IBPOOL_PREALLOC_BUFFERS = 0; - -GrContext* GrContext::Create(GrEngine engine, - GrPlatform3DContext context3D) { - GrContext* ctx = NULL; - GrGpu* fGpu = GrGpu::Create(engine, context3D); - if (NULL != fGpu) { - ctx = new GrContext(fGpu); - fGpu->unref(); - } - return ctx; -} - -GrContext* GrContext::CreateGLShaderContext() { - return GrContext::Create(kOpenGL_Shaders_GrEngine, 0); -} - -GrContext::~GrContext() { - this->flush(); - delete fTextureCache; - delete fFontCache; - delete fDrawBuffer; - delete fDrawBufferVBAllocPool; - delete fDrawBufferIBAllocPool; - GrSafeUnref(fCustomPathRenderer); - GrSafeUnref(fAAFillRectIndexBuffer); - GrSafeUnref(fAAStrokeRectIndexBuffer); - fGpu->unref(); -} - -void GrContext::contextLost() { - contextDestroyed(); - this->setupDrawBuffer(); -} - -void GrContext::contextDestroyed() { - // abandon first to so destructors - // don't try to free the resources in the API. - fGpu->abandonResources(); - - delete fDrawBuffer; - fDrawBuffer = NULL; - - delete fDrawBufferVBAllocPool; - fDrawBufferVBAllocPool = NULL; - - delete fDrawBufferIBAllocPool; - fDrawBufferIBAllocPool = NULL; - - GrSafeSetNull(fAAFillRectIndexBuffer); - GrSafeSetNull(fAAStrokeRectIndexBuffer); - - fTextureCache->removeAll(); - fFontCache->freeAll(); - fGpu->markContextDirty(); -} - -void GrContext::resetContext() { - fGpu->markContextDirty(); -} - -void GrContext::freeGpuResources() { - this->flush(); - fTextureCache->removeAll(); - fFontCache->freeAll(); -} - -//////////////////////////////////////////////////////////////////////////////// - -int GrContext::PaintStageVertexLayoutBits( - const GrPaint& paint, - const bool hasTexCoords[GrPaint::kTotalStages]) { - int stageMask = paint.getActiveStageMask(); - int layout = 0; - for (int i = 0; i < GrPaint::kTotalStages; ++i) { - if ((1 << i) & stageMask) { - if (NULL != hasTexCoords && hasTexCoords[i]) { - layout |= GrDrawTarget::StageTexCoordVertexLayoutBit(i, i); - } else { - layout |= GrDrawTarget::StagePosAsTexCoordVertexLayoutBit(i); - } - } - } - return layout; -} - - -//////////////////////////////////////////////////////////////////////////////// - -enum { - kNPOTBit = 0x1, - kFilterBit = 0x2, - kKeylessBit = 0x4, -}; - -bool GrContext::finalizeTextureKey(GrTextureKey* key, - const GrSamplerState& sampler, - bool keyless) const { - uint32_t bits = 0; - uint16_t width = key->width(); - uint16_t height = key->height(); - - if (!fGpu->npotTextureTileSupport()) { - bool isPow2 = GrIsPow2(width) && GrIsPow2(height); - - bool tiled = (sampler.getWrapX() != GrSamplerState::kClamp_WrapMode) || - (sampler.getWrapY() != GrSamplerState::kClamp_WrapMode); - - if (tiled && !isPow2) { - bits |= kNPOTBit; - if (GrSamplerState::kNearest_Filter != sampler.getFilter()) { - bits |= kFilterBit; - } - } - } - - if (keyless) { - bits |= kKeylessBit; - } - key->finalize(bits); - return 0 != bits; -} - -GrTextureEntry* GrContext::findAndLockTexture(GrTextureKey* key, - const GrSamplerState& sampler) { - finalizeTextureKey(key, sampler, false); - return fTextureCache->findAndLock(*key); -} - -static void stretchImage(void* dst, - int dstW, - int dstH, - void* src, - int srcW, - int srcH, - int bpp) { - GrFixed dx = (srcW << 16) / dstW; - GrFixed dy = (srcH << 16) / dstH; - - GrFixed y = dy >> 1; - - int dstXLimit = dstW*bpp; - for (int j = 0; j < dstH; ++j) { - GrFixed x = dx >> 1; - void* srcRow = (uint8_t*)src + (y>>16)*srcW*bpp; - void* dstRow = (uint8_t*)dst + j*dstW*bpp; - for (int i = 0; i < dstXLimit; i += bpp) { - memcpy((uint8_t*) dstRow + i, - (uint8_t*) srcRow + (x>>16)*bpp, - bpp); - x += dx; - } - y += dy; - } -} - -GrTextureEntry* GrContext::createAndLockTexture(GrTextureKey* key, - const GrSamplerState& sampler, - const GrTextureDesc& desc, - void* srcData, size_t rowBytes) { - GrAssert(key->width() == desc.fWidth); - GrAssert(key->height() == desc.fHeight); - -#if GR_DUMP_TEXTURE_UPLOAD - GrPrintf("GrContext::createAndLockTexture [%d %d]\n", desc.fWidth, desc.fHeight); -#endif - - GrTextureEntry* entry = NULL; - bool special = finalizeTextureKey(key, sampler, false); - if (special) { - GrTextureEntry* clampEntry; - GrTextureKey clampKey(*key); - clampEntry = findAndLockTexture(&clampKey, GrSamplerState::ClampNoFilter()); - - if (NULL == clampEntry) { - clampEntry = createAndLockTexture(&clampKey, - GrSamplerState::ClampNoFilter(), - desc, srcData, rowBytes); - GrAssert(NULL != clampEntry); - if (NULL == clampEntry) { - return NULL; - } - } - GrTextureDesc rtDesc = desc; - rtDesc.fFlags = rtDesc.fFlags | - kRenderTarget_GrTextureFlagBit | - kNoStencil_GrTextureFlagBit; - rtDesc.fWidth = GrNextPow2(GrMax<int>(desc.fWidth, - fGpu->minRenderTargetWidth())); - rtDesc.fHeight = GrNextPow2(GrMax<int>(desc.fHeight, - fGpu->minRenderTargetHeight())); - - GrTexture* texture = fGpu->createTexture(rtDesc, NULL, 0); - - if (NULL != texture) { - GrDrawTarget::AutoStateRestore asr(fGpu); - fGpu->setRenderTarget(texture->asRenderTarget()); - fGpu->setTexture(0, clampEntry->texture()); - fGpu->disableStencil(); - fGpu->setViewMatrix(GrMatrix::I()); - fGpu->setAlpha(0xff); - fGpu->setBlendFunc(kOne_BlendCoeff, kZero_BlendCoeff); - fGpu->disableState(GrDrawTarget::kDither_StateBit | - GrDrawTarget::kClip_StateBit | - GrDrawTarget::kAntialias_StateBit); - GrSamplerState::Filter filter; - // if filtering is not desired then we want to ensure all - // texels in the resampled image are copies of texels from - // the original. - if (GrSamplerState::kNearest_Filter == sampler.getFilter()) { - filter = GrSamplerState::kNearest_Filter; - } else { - filter = GrSamplerState::kBilinear_Filter; - } - GrSamplerState stretchSampler(GrSamplerState::kClamp_WrapMode, - GrSamplerState::kClamp_WrapMode, - filter); - fGpu->setSamplerState(0, stretchSampler); - - static const GrVertexLayout layout = - GrDrawTarget::StageTexCoordVertexLayoutBit(0,0); - GrDrawTarget::AutoReleaseGeometry arg(fGpu, layout, 4, 0); - - if (arg.succeeded()) { - GrPoint* verts = (GrPoint*) arg.vertices(); - verts[0].setIRectFan(0, 0, - texture->width(), - texture->height(), - 2*sizeof(GrPoint)); - verts[1].setIRectFan(0, 0, 1, 1, 2*sizeof(GrPoint)); - fGpu->drawNonIndexed(kTriangleFan_PrimitiveType, - 0, 4); - entry = fTextureCache->createAndLock(*key, texture); - } - texture->releaseRenderTarget(); - } else { - // TODO: Our CPU stretch doesn't filter. But we create separate - // stretched textures when the sampler state is either filtered or - // not. Either implement filtered stretch blit on CPU or just create - // one when FBO case fails. - - rtDesc.fFlags = kNone_GrTextureFlags; - // no longer need to clamp at min RT size. - rtDesc.fWidth = GrNextPow2(desc.fWidth); - rtDesc.fHeight = GrNextPow2(desc.fHeight); - int bpp = GrBytesPerPixel(desc.fFormat); - GrAutoSMalloc<128*128*4> stretchedPixels(bpp * - rtDesc.fWidth * - rtDesc.fHeight); - stretchImage(stretchedPixels.get(), rtDesc.fWidth, rtDesc.fHeight, - srcData, desc.fWidth, desc.fHeight, bpp); - - size_t stretchedRowBytes = rtDesc.fWidth * bpp; - - GrTexture* texture = fGpu->createTexture(rtDesc, - stretchedPixels.get(), - stretchedRowBytes); - GrAssert(NULL != texture); - entry = fTextureCache->createAndLock(*key, texture); - } - fTextureCache->unlock(clampEntry); - - } else { - GrTexture* texture = fGpu->createTexture(desc, srcData, rowBytes); - if (NULL != texture) { - entry = fTextureCache->createAndLock(*key, texture); - } else { - entry = NULL; - } - } - return entry; -} - -GrTextureEntry* GrContext::lockKeylessTexture(const GrTextureDesc& desc) { - uint32_t p0 = desc.fFormat; - uint32_t p1 = (desc.fAALevel << 16) | desc.fFlags; - GrTextureKey key(p0, p1, desc.fWidth, desc.fHeight); - this->finalizeTextureKey(&key, GrSamplerState::ClampNoFilter(), true); - - GrTextureEntry* entry = fTextureCache->findAndLock(key); - if (NULL == entry) { - GrTexture* texture = fGpu->createTexture(desc, NULL, 0); - if (NULL != texture) { - entry = fTextureCache->createAndLock(key, texture); - } - } - // If the caller gives us the same desc/sampler twice we don't want - // to return the same texture the second time (unless it was previously - // released). So we detach the entry from the cache and reattach at release. - if (NULL != entry) { - fTextureCache->detach(entry); - } - return entry; -} - -void GrContext::unlockTexture(GrTextureEntry* entry) { - if (kKeylessBit & entry->key().getPrivateBits()) { - fTextureCache->reattachAndUnlock(entry); - } else { - fTextureCache->unlock(entry); - } -} - -GrTexture* GrContext::createUncachedTexture(const GrTextureDesc& desc, - void* srcData, - size_t rowBytes) { - return fGpu->createTexture(desc, srcData, rowBytes); -} - -void GrContext::getTextureCacheLimits(int* maxTextures, - size_t* maxTextureBytes) const { - fTextureCache->getLimits(maxTextures, maxTextureBytes); -} - -void GrContext::setTextureCacheLimits(int maxTextures, size_t maxTextureBytes) { - fTextureCache->setLimits(maxTextures, maxTextureBytes); -} - -int GrContext::getMaxTextureDimension() { - return fGpu->maxTextureDimension(); -} - -/////////////////////////////////////////////////////////////////////////////// - -GrResource* GrContext::createPlatformSurface(const GrPlatformSurfaceDesc& desc) { - // validate flags here so that GrGpu subclasses don't have to check - if (kTexture_GrPlatformSurfaceType == desc.fSurfaceType && - 0 != desc.fRenderTargetFlags) { - return NULL; - } - if (!(kIsMultisampled_GrPlatformRenderTargetFlagBit & desc.fRenderTargetFlags) && - (kGrCanResolve_GrPlatformRenderTargetFlagBit & desc.fRenderTargetFlags)) { - return NULL; - } - if (kTextureRenderTarget_GrPlatformSurfaceType == desc.fSurfaceType && - (kIsMultisampled_GrPlatformRenderTargetFlagBit & desc.fRenderTargetFlags) && - !(kGrCanResolve_GrPlatformRenderTargetFlagBit & desc.fRenderTargetFlags)) { - return NULL; - } - return fGpu->createPlatformSurface(desc); -} - -GrRenderTarget* GrContext::createRenderTargetFrom3DApiState() { - return fGpu->createRenderTargetFrom3DApiState(); -} - -/////////////////////////////////////////////////////////////////////////////// - -bool GrContext::supportsIndex8PixelConfig(const GrSamplerState& sampler, - int width, int height) { - if (!fGpu->supports8BitPalette()) { - return false; - } - - - bool isPow2 = GrIsPow2(width) && GrIsPow2(height); - - if (!isPow2) { - if (!fGpu->npotTextureSupport()) { - return false; - } - - bool tiled = sampler.getWrapX() != GrSamplerState::kClamp_WrapMode || - sampler.getWrapY() != GrSamplerState::kClamp_WrapMode; - if (tiled && !fGpu->npotTextureTileSupport()) { - return false; - } - } - return true; -} - -//////////////////////////////////////////////////////////////////////////////// - -const GrClip& GrContext::getClip() const { return fGpu->getClip(); } - -void GrContext::setClip(const GrClip& clip) { - fGpu->setClip(clip); - fGpu->enableState(GrDrawTarget::kClip_StateBit); -} - -void GrContext::setClip(const GrIRect& rect) { - GrClip clip; - clip.setFromIRect(rect); - fGpu->setClip(clip); -} - -//////////////////////////////////////////////////////////////////////////////// - -void GrContext::clear(const GrIRect* rect, const GrColor color) { - this->flush(); - fGpu->clear(rect, color); -} - -void GrContext::drawPaint(const GrPaint& paint) { - // set rect to be big enough to fill the space, but not super-huge, so we - // don't overflow fixed-point implementations - GrRect r; - r.setLTRB(0, 0, - GrIntToScalar(getRenderTarget()->width()), - GrIntToScalar(getRenderTarget()->height())); - GrMatrix inverse; - if (fGpu->getViewInverse(&inverse)) { - inverse.mapRect(&r); - } else { - GrPrintf("---- fGpu->getViewInverse failed\n"); - } - this->drawRect(paint, r); -} - -//////////////////////////////////////////////////////////////////////////////// - -bool GrContext::doOffscreenAA(GrDrawTarget* target, - const GrPaint& paint, - bool isLines) const { -#if GR_MAX_OFFSCREEN_AA_DIM==0 - return false; -#else - if (!paint.fAntiAlias) { - return false; - } - if (isLines && fGpu->supportsAALines()) { - return false; - } - if (target->getRenderTarget()->isMultisampled()) { - return false; - } - // we have to be sure that the blend equation is expressible - // as simple src / dst coeffecients when the source - // is already modulated by the coverage fraction. - // We could use dual-source blending to get the correct per-pixel - // dst coeffecient for the remaining cases. - if (kISC_BlendCoeff != paint.fDstBlendCoeff && - kOne_BlendCoeff != paint.fDstBlendCoeff && - kISA_BlendCoeff != paint.fDstBlendCoeff) { - return false; - } - return true; -#endif -} - -bool GrContext::setupOffscreenAAPass1(GrDrawTarget* target, - bool requireStencil, - const GrIRect& boundRect, - OffscreenRecord* record) { - GrAssert(GR_MAX_OFFSCREEN_AA_DIM > 0); - - GrAssert(NULL == record->fEntry0); - GrAssert(NULL == record->fEntry1); - - int boundW = boundRect.width(); - int boundH = boundRect.height(); - int size = GrMax(64, (int)GrNextPow2(GrMax(boundW, boundH))); - - GrTextureDesc desc; - if (requireStencil) { - desc.fFlags = kRenderTarget_GrTextureFlagBit; - } else { - desc.fFlags = kRenderTarget_GrTextureFlagBit | - kNoStencil_GrTextureFlagBit; - } - - desc.fFormat = kRGBA_8888_GrPixelConfig; - - int scale; - // Using MSAA seems to be slower for some yet unknown reason. - if (false && fGpu->supportsFullsceneAA()) { - record->fDownsample = OffscreenRecord::kFSAA_Downsample; - scale = GR_Scalar1; - desc.fAALevel = kMed_GrAALevel; - } else { - record->fDownsample = (fGpu->supports4x4DownsampleFilter()) ? - OffscreenRecord::k4x4SinglePass_Downsample : - OffscreenRecord::k4x4TwoPass_Downsample; - scale = 4; - desc.fAALevel = kNone_GrAALevel; - } - - desc.fWidth = scale * size; - desc.fHeight = scale * size; - - record->fEntry0 = this->lockKeylessTexture(desc); - - if (NULL == record->fEntry0) { - return false; - } - - if (OffscreenRecord::k4x4TwoPass_Downsample == record->fDownsample) { - desc.fWidth /= 2; - desc.fHeight /= 2; - record->fEntry1 = this->lockKeylessTexture(desc); - if (NULL == record->fEntry1) { - this->unlockTexture(record->fEntry0); - record->fEntry0 = NULL; - return false; - } - } - - GrRenderTarget* offRT0 = record->fEntry0->texture()->asRenderTarget(); - GrAssert(NULL != offRT0); - - target->saveCurrentDrawState(&record->fSavedState); - - GrPaint tempPaint; - tempPaint.reset(); - SetPaint(tempPaint, target); - target->setRenderTarget(offRT0); - - GrMatrix transM; - transM.setTranslate(-boundRect.fLeft, -boundRect.fTop); - target->postConcatViewMatrix(transM); - GrMatrix scaleM; - scaleM.setScale(scale * GR_Scalar1, scale * GR_Scalar1); - target->postConcatViewMatrix(scaleM); - - // clip gets applied in second pass - target->disableState(GrDrawTarget::kClip_StateBit); - - GrIRect clear = SkIRect::MakeWH(scale * boundW, scale * boundH); - target->clear(&clear, 0x0); - - return true; -} - -void GrContext::offscreenAAPass2(GrDrawTarget* target, - const GrPaint& paint, - const GrIRect& boundRect, - OffscreenRecord* record) { - - GrAssert(NULL != record->fEntry0); - - GrSamplerState::Filter filter; - if (OffscreenRecord::k4x4SinglePass_Downsample == record->fDownsample) { - filter = GrSamplerState::k4x4Downsample_Filter; - } else { - filter = GrSamplerState::kBilinear_Filter; - } - - GrMatrix sampleM; - GrSamplerState sampler(GrSamplerState::kClamp_WrapMode, - GrSamplerState::kClamp_WrapMode, filter); - - GrTexture* src = record->fEntry0->texture(); - int scale; - - enum { - kOffscreenStage = GrPaint::kTotalStages, - }; - - if (OffscreenRecord::k4x4TwoPass_Downsample == record->fDownsample) { - GrAssert(NULL != record->fEntry1); - scale = 2; - GrRenderTarget* dst = record->fEntry1->texture()->asRenderTarget(); - - // Do 2x2 downsample from first to second - target->setTexture(kOffscreenStage, src); - target->setRenderTarget(dst); - target->setViewMatrix(GrMatrix::I()); - sampleM.setScale(scale * GR_Scalar1 / src->width(), - scale * GR_Scalar1 / src->height()); - sampler.setMatrix(sampleM); - target->setSamplerState(kOffscreenStage, sampler); - GrRect rect = SkRect::MakeWH(scale * boundRect.width(), - scale * boundRect.height()); - target->drawSimpleRect(rect, NULL, 1 << kOffscreenStage); - - src = record->fEntry1->texture(); - } else if (OffscreenRecord::kFSAA_Downsample == record->fDownsample) { - scale = 1; - GrIRect rect = SkIRect::MakeWH(boundRect.width(), boundRect.height()); - src->asRenderTarget()->overrideResolveRect(rect); - } else { - GrAssert(OffscreenRecord::k4x4SinglePass_Downsample == - record->fDownsample); - scale = 4; - } - - // setup for draw back to main RT - int stageMask = paint.getActiveStageMask(); - - target->restoreDrawState(record->fSavedState); - - if (stageMask) { - GrMatrix invVM; - if (target->getViewInverse(&invVM)) { - target->preConcatSamplerMatrices(stageMask, invVM); - } - } - target->setViewMatrix(GrMatrix::I()); - - target->setTexture(kOffscreenStage, src); - sampleM.setScale(scale * GR_Scalar1 / src->width(), - scale * GR_Scalar1 / src->height()); - sampler.setMatrix(sampleM); - sampleM.setTranslate(-boundRect.fLeft, -boundRect.fTop); - sampler.preConcatMatrix(sampleM); - target->setSamplerState(kOffscreenStage, sampler); - - GrRect dstRect; - int stages = (1 << kOffscreenStage) | stageMask; - dstRect.set(boundRect); - target->drawSimpleRect(dstRect, NULL, stages); - - this->unlockTexture(record->fEntry0); - record->fEntry0 = NULL; - if (NULL != record->fEntry1) { - this->unlockTexture(record->fEntry1); - record->fEntry1 = NULL; - } - target->restoreDrawState(record->fSavedState); -} - -//////////////////////////////////////////////////////////////////////////////// - -/* create a triangle strip that strokes the specified triangle. There are 8 - unique vertices, but we repreat the last 2 to close up. Alternatively we - could use an indices array, and then only send 8 verts, but not sure that - would be faster. - */ -static void setStrokeRectStrip(GrPoint verts[10], GrRect rect, - GrScalar width) { - const GrScalar rad = GrScalarHalf(width); - rect.sort(); - - verts[0].set(rect.fLeft + rad, rect.fTop + rad); - verts[1].set(rect.fLeft - rad, rect.fTop - rad); - verts[2].set(rect.fRight - rad, rect.fTop + rad); - verts[3].set(rect.fRight + rad, rect.fTop - rad); - verts[4].set(rect.fRight - rad, rect.fBottom - rad); - verts[5].set(rect.fRight + rad, rect.fBottom + rad); - verts[6].set(rect.fLeft + rad, rect.fBottom - rad); - verts[7].set(rect.fLeft - rad, rect.fBottom + rad); - verts[8] = verts[0]; - verts[9] = verts[1]; -} - -static GrColor getColorForMesh(const GrPaint& paint) { - // FIXME: This was copied from SkGpuDevice, seems like - // we should have already smeared a in caller if that - // is what is desired. - if (paint.hasTexture()) { - unsigned a = GrColorUnpackA(paint.fColor); - return GrColorPackRGBA(a, a, a, a); - } else { - return paint.fColor; - } -} - -static void setInsetFan(GrPoint* pts, size_t stride, - const GrRect& r, GrScalar dx, GrScalar dy) { - pts->setRectFan(r.fLeft + dx, r.fTop + dy, r.fRight - dx, r.fBottom - dy, stride); -} - -static const uint16_t gFillAARectIdx[] = { - 0, 1, 5, 5, 4, 0, - 1, 2, 6, 6, 5, 1, - 2, 3, 7, 7, 6, 2, - 3, 0, 4, 4, 7, 3, - 4, 5, 6, 6, 7, 4, -}; - -int GrContext::aaFillRectIndexCount() const { - return GR_ARRAY_COUNT(gFillAARectIdx); -} - -GrIndexBuffer* GrContext::aaFillRectIndexBuffer() { - if (NULL == fAAFillRectIndexBuffer) { - fAAFillRectIndexBuffer = fGpu->createIndexBuffer(sizeof(gFillAARectIdx), - false); - GrAssert(NULL != fAAFillRectIndexBuffer); -#if GR_DEBUG - bool updated = -#endif - fAAFillRectIndexBuffer->updateData(gFillAARectIdx, - sizeof(gFillAARectIdx)); - GR_DEBUGASSERT(updated); - } - return fAAFillRectIndexBuffer; -} - -static const uint16_t gStrokeAARectIdx[] = { - 0 + 0, 1 + 0, 5 + 0, 5 + 0, 4 + 0, 0 + 0, - 1 + 0, 2 + 0, 6 + 0, 6 + 0, 5 + 0, 1 + 0, - 2 + 0, 3 + 0, 7 + 0, 7 + 0, 6 + 0, 2 + 0, - 3 + 0, 0 + 0, 4 + 0, 4 + 0, 7 + 0, 3 + 0, - - 0 + 4, 1 + 4, 5 + 4, 5 + 4, 4 + 4, 0 + 4, - 1 + 4, 2 + 4, 6 + 4, 6 + 4, 5 + 4, 1 + 4, - 2 + 4, 3 + 4, 7 + 4, 7 + 4, 6 + 4, 2 + 4, - 3 + 4, 0 + 4, 4 + 4, 4 + 4, 7 + 4, 3 + 4, - - 0 + 8, 1 + 8, 5 + 8, 5 + 8, 4 + 8, 0 + 8, - 1 + 8, 2 + 8, 6 + 8, 6 + 8, 5 + 8, 1 + 8, - 2 + 8, 3 + 8, 7 + 8, 7 + 8, 6 + 8, 2 + 8, - 3 + 8, 0 + 8, 4 + 8, 4 + 8, 7 + 8, 3 + 8, -}; - -int GrContext::aaStrokeRectIndexCount() const { - return GR_ARRAY_COUNT(gStrokeAARectIdx); -} - -GrIndexBuffer* GrContext::aaStrokeRectIndexBuffer() { - if (NULL == fAAStrokeRectIndexBuffer) { - fAAStrokeRectIndexBuffer = fGpu->createIndexBuffer(sizeof(gStrokeAARectIdx), - false); - GrAssert(NULL != fAAStrokeRectIndexBuffer); -#if GR_DEBUG - bool updated = -#endif - fAAStrokeRectIndexBuffer->updateData(gStrokeAARectIdx, - sizeof(gStrokeAARectIdx)); - GR_DEBUGASSERT(updated); - } - return fAAStrokeRectIndexBuffer; -} - -void GrContext::fillAARect(GrDrawTarget* target, - const GrPaint& paint, - const GrRect& devRect) { - - GrVertexLayout layout = PaintStageVertexLayoutBits(paint, NULL) | - GrDrawTarget::kColor_VertexLayoutBit; - - size_t vsize = GrDrawTarget::VertexSize(layout); - - GrDrawTarget::AutoReleaseGeometry geo(target, layout, 8, 0); - - intptr_t verts = reinterpret_cast<intptr_t>(geo.vertices()); - - GrPoint* fan0Pos = reinterpret_cast<GrPoint*>(verts); - GrPoint* fan1Pos = reinterpret_cast<GrPoint*>(verts + 4 * vsize); - - setInsetFan(fan0Pos, vsize, devRect, -GR_ScalarHalf, -GR_ScalarHalf); - setInsetFan(fan1Pos, vsize, devRect, GR_ScalarHalf, GR_ScalarHalf); - - verts += sizeof(GrPoint); - for (int i = 0; i < 4; ++i) { - *reinterpret_cast<GrColor*>(verts + i * vsize) = 0; - } - - GrColor innerColor = getColorForMesh(paint); - verts += 4 * vsize; - for (int i = 0; i < 4; ++i) { - *reinterpret_cast<GrColor*>(verts + i * vsize) = innerColor; - } - - target->setIndexSourceToBuffer(this->aaFillRectIndexBuffer()); - - target->drawIndexed(kTriangles_PrimitiveType, 0, - 0, 8, this->aaFillRectIndexCount()); -} - -void GrContext::strokeAARect(GrDrawTarget* target, const GrPaint& paint, - const GrRect& devRect, const GrVec& devStrokeSize) { - const GrScalar& dx = devStrokeSize.fX; - const GrScalar& dy = devStrokeSize.fY; - const GrScalar rx = GrMul(dx, GR_ScalarHalf); - const GrScalar ry = GrMul(dy, GR_ScalarHalf); - - GrVertexLayout layout = PaintStageVertexLayoutBits(paint, NULL) | - GrDrawTarget::kColor_VertexLayoutBit; - - GrScalar spare; - { - GrScalar w = devRect.width() - dx; - GrScalar h = devRect.height() - dy; - spare = GrMin(w, h); - } - - if (spare <= 0) { - GrRect r(devRect); - r.inset(-rx, -ry); - fillAARect(target, paint, r); - return; - } - - size_t vsize = GrDrawTarget::VertexSize(layout); - - GrDrawTarget::AutoReleaseGeometry geo(target, layout, 16, 0); - - intptr_t verts = reinterpret_cast<intptr_t>(geo.vertices()); - - GrPoint* fan0Pos = reinterpret_cast<GrPoint*>(verts); - GrPoint* fan1Pos = reinterpret_cast<GrPoint*>(verts + 4 * vsize); - GrPoint* fan2Pos = reinterpret_cast<GrPoint*>(verts + 8 * vsize); - GrPoint* fan3Pos = reinterpret_cast<GrPoint*>(verts + 12 * vsize); - - setInsetFan(fan0Pos, vsize, devRect, -rx - GR_ScalarHalf, -ry - GR_ScalarHalf); - setInsetFan(fan1Pos, vsize, devRect, -rx + GR_ScalarHalf, -ry + GR_ScalarHalf); - setInsetFan(fan2Pos, vsize, devRect, rx - GR_ScalarHalf, ry - GR_ScalarHalf); - setInsetFan(fan3Pos, vsize, devRect, rx + GR_ScalarHalf, ry + GR_ScalarHalf); - - verts += sizeof(GrPoint); - for (int i = 0; i < 4; ++i) { - *reinterpret_cast<GrColor*>(verts + i * vsize) = 0; - } - - GrColor innerColor = getColorForMesh(paint); - verts += 4 * vsize; - for (int i = 0; i < 8; ++i) { - *reinterpret_cast<GrColor*>(verts + i * vsize) = innerColor; - } - - verts += 8 * vsize; - for (int i = 0; i < 8; ++i) { - *reinterpret_cast<GrColor*>(verts + i * vsize) = 0; - } - - target->setIndexSourceToBuffer(aaStrokeRectIndexBuffer()); - target->drawIndexed(kTriangles_PrimitiveType, - 0, 0, 16, aaStrokeRectIndexCount()); -} - -/** - * Returns true if the rects edges are integer-aligned. - */ -static bool isIRect(const GrRect& r) { - return GrScalarIsInt(r.fLeft) && GrScalarIsInt(r.fTop) && - GrScalarIsInt(r.fRight) && GrScalarIsInt(r.fBottom); -} - -static bool apply_aa_to_rect(GrDrawTarget* target, - GrGpu* gpu, - const GrPaint& paint, - const GrRect& rect, - GrScalar width, - const GrMatrix* matrix, - GrMatrix* combinedMatrix, - GrRect* devRect) { - // we use a simple alpha ramp to do aa on axis-aligned rects - // do AA with alpha ramp if the caller requested AA, the rect - // will be axis-aligned,the render target is not - // multisampled, and the rect won't land on integer coords. - - if (!paint.fAntiAlias) { - return false; - } - - if (target->getRenderTarget()->isMultisampled()) { - return false; - } - - if (0 == width && gpu->supportsAALines()) { - return false; - } - - if (!target->getViewMatrix().preservesAxisAlignment()) { - return false; - } - - if (NULL != matrix && - !matrix->preservesAxisAlignment()) { - return false; - } - - *combinedMatrix = target->getViewMatrix(); - if (NULL != matrix) { - combinedMatrix->preConcat(*matrix); - GrAssert(combinedMatrix->preservesAxisAlignment()); - } - - combinedMatrix->mapRect(devRect, rect); - devRect->sort(); - - if (width < 0) { - return !isIRect(*devRect); - } else { - return true; - } -} - -void GrContext::drawRect(const GrPaint& paint, - const GrRect& rect, - GrScalar width, - const GrMatrix* matrix) { - - - GrDrawTarget* target = this->prepareToDraw(paint, kUnbuffered_DrawCategory); - int stageMask = paint.getActiveStageMask(); - - GrRect devRect = rect; - GrMatrix combinedMatrix; - bool doAA = apply_aa_to_rect(target, fGpu, paint, rect, width, matrix, - &combinedMatrix, &devRect); - - if (doAA) { - GrDrawTarget::AutoViewMatrixRestore avm(target); - if (stageMask) { - GrMatrix inv; - if (combinedMatrix.invert(&inv)) { - target->preConcatSamplerMatrices(stageMask, inv); - } - } - target->setViewMatrix(GrMatrix::I()); - if (width >= 0) { - GrVec strokeSize;; - if (width > 0) { - strokeSize.set(width, width); - combinedMatrix.mapVectors(&strokeSize, 1); - strokeSize.setAbs(strokeSize); - } else { - strokeSize.set(GR_Scalar1, GR_Scalar1); - } - strokeAARect(target, paint, devRect, strokeSize); - } else { - fillAARect(target, paint, devRect); - } - return; - } - - if (width >= 0) { - // TODO: consider making static vertex buffers for these cases. - // Hairline could be done by just adding closing vertex to - // unitSquareVertexBuffer() - GrVertexLayout layout = PaintStageVertexLayoutBits(paint, NULL); - - static const int worstCaseVertCount = 10; - GrDrawTarget::AutoReleaseGeometry geo(target, layout, worstCaseVertCount, 0); - - if (!geo.succeeded()) { - return; - } - - GrPrimitiveType primType; - int vertCount; - GrPoint* vertex = geo.positions(); - - if (width > 0) { - vertCount = 10; - primType = kTriangleStrip_PrimitiveType; - setStrokeRectStrip(vertex, rect, width); - } else { - // hairline - vertCount = 5; - primType = kLineStrip_PrimitiveType; - vertex[0].set(rect.fLeft, rect.fTop); - vertex[1].set(rect.fRight, rect.fTop); - vertex[2].set(rect.fRight, rect.fBottom); - vertex[3].set(rect.fLeft, rect.fBottom); - vertex[4].set(rect.fLeft, rect.fTop); - } - - GrDrawTarget::AutoViewMatrixRestore avmr; - if (NULL != matrix) { - avmr.set(target); - target->preConcatViewMatrix(*matrix); - target->preConcatSamplerMatrices(stageMask, *matrix); - } - - target->drawNonIndexed(primType, 0, vertCount); - } else { - #if GR_STATIC_RECT_VB - GrVertexLayout layout = PaintStageVertexLayoutBits(paint, NULL); - - target->setVertexSourceToBuffer(layout, - fGpu->getUnitSquareVertexBuffer()); - GrDrawTarget::AutoViewMatrixRestore avmr(target); - GrMatrix m; - m.setAll(rect.width(), 0, rect.fLeft, - 0, rect.height(), rect.fTop, - 0, 0, GrMatrix::I()[8]); - - if (NULL != matrix) { - m.postConcat(*matrix); - } - - target->preConcatViewMatrix(m); - target->preConcatSamplerMatrices(stageMask, m); - - target->drawNonIndexed(kTriangleFan_PrimitiveType, 0, 4); - #else - target->drawSimpleRect(rect, matrix, stageMask); - #endif - } -} - -void GrContext::drawRectToRect(const GrPaint& paint, - const GrRect& dstRect, - const GrRect& srcRect, - const GrMatrix* dstMatrix, - const GrMatrix* srcMatrix) { - - // srcRect refers to paint's first texture - if (NULL == paint.getTexture(0)) { - drawRect(paint, dstRect, -1, dstMatrix); - return; - } - - GR_STATIC_ASSERT(!BATCH_RECT_TO_RECT || !GR_STATIC_RECT_VB); - -#if GR_STATIC_RECT_VB - GrDrawTarget* target = this->prepareToDraw(paint, kUnbuffered_DrawCategory); - - GrVertexLayout layout = PaintStageVertexLayoutBits(paint, NULL); - GrDrawTarget::AutoViewMatrixRestore avmr(target); - - GrMatrix m; - - m.setAll(dstRect.width(), 0, dstRect.fLeft, - 0, dstRect.height(), dstRect.fTop, - 0, 0, GrMatrix::I()[8]); - if (NULL != dstMatrix) { - m.postConcat(*dstMatrix); - } - target->preConcatViewMatrix(m); - - // srcRect refers to first stage - int otherStageMask = paint.getActiveStageMask() & - (~(1 << GrPaint::kFirstTextureStage)); - if (otherStageMask) { - target->preConcatSamplerMatrices(otherStageMask, m); - } - - m.setAll(srcRect.width(), 0, srcRect.fLeft, - 0, srcRect.height(), srcRect.fTop, - 0, 0, GrMatrix::I()[8]); - if (NULL != srcMatrix) { - m.postConcat(*srcMatrix); - } - target->preConcatSamplerMatrix(GrPaint::kFirstTextureStage, m); - - target->setVertexSourceToBuffer(layout, fGpu->getUnitSquareVertexBuffer()); - target->drawNonIndexed(kTriangleFan_PrimitiveType, 0, 4); -#else - - GrDrawTarget* target; -#if BATCH_RECT_TO_RECT - target = this->prepareToDraw(paint, kBuffered_DrawCategory); -#else - target = this->prepareToDraw(paint, kUnbuffered_DrawCategory); -#endif - - const GrRect* srcRects[GrDrawTarget::kNumStages] = {NULL}; - const GrMatrix* srcMatrices[GrDrawTarget::kNumStages] = {NULL}; - srcRects[0] = &srcRect; - srcMatrices[0] = srcMatrix; - - target->drawRect(dstRect, dstMatrix, 1, srcRects, srcMatrices); -#endif -} - -void GrContext::drawVertices(const GrPaint& paint, - GrPrimitiveType primitiveType, - int vertexCount, - const GrPoint positions[], - const GrPoint texCoords[], - const GrColor colors[], - const uint16_t indices[], - int indexCount) { - - GrDrawTarget::AutoReleaseGeometry geo; - - GrDrawTarget* target = this->prepareToDraw(paint, kUnbuffered_DrawCategory); - - bool hasTexCoords[GrPaint::kTotalStages] = { - NULL != texCoords, // texCoordSrc provides explicit stage 0 coords - 0 // remaining stages use positions - }; - - GrVertexLayout layout = PaintStageVertexLayoutBits(paint, hasTexCoords); - - if (NULL != colors) { - layout |= GrDrawTarget::kColor_VertexLayoutBit; - } - int vertexSize = GrDrawTarget::VertexSize(layout); - - bool doAA = false; - OffscreenRecord record; - GrIRect bounds; - - if (sizeof(GrPoint) != vertexSize) { - if (!geo.set(target, layout, vertexCount, 0)) { - GrPrintf("Failed to get space for vertices!"); - return; - } - int texOffsets[GrDrawTarget::kMaxTexCoords]; - int colorOffset; - GrDrawTarget::VertexSizeAndOffsetsByIdx(layout, - texOffsets, - &colorOffset); - void* curVertex = geo.vertices(); - - for (int i = 0; i < vertexCount; ++i) { - *((GrPoint*)curVertex) = positions[i]; - - if (texOffsets[0] > 0) { - *(GrPoint*)((intptr_t)curVertex + texOffsets[0]) = texCoords[i]; - } - if (colorOffset > 0) { - *(GrColor*)((intptr_t)curVertex + colorOffset) = colors[i]; - } - curVertex = (void*)((intptr_t)curVertex + vertexSize); - } - } else { - // we don't do offscreen AA when we have per-vertex tex coords or colors - if (this->doOffscreenAA(target, paint, GrIsPrimTypeLines(primitiveType))) { - GrRect b; - b.setBounds(positions, vertexCount); - target->getViewMatrix().mapRect(&b); - b.roundOut(&bounds); - - if (this->setupOffscreenAAPass1(target, false, bounds, &record)) { - doAA = true; - } - } - target->setVertexSourceToArray(layout, positions, vertexCount); - } - - if (NULL != indices) { - target->setIndexSourceToArray(indices, indexCount); - } - - if (NULL != indices) { - target->drawIndexed(primitiveType, 0, 0, vertexCount, indexCount); - } else { - target->drawNonIndexed(primitiveType, 0, vertexCount); - } - - if (doAA) { - this->offscreenAAPass2(target, paint, bounds, &record); - } -} - - -/////////////////////////////////////////////////////////////////////////////// - -void GrContext::drawPath(const GrPaint& paint, const GrPath& path, - GrPathFill fill, const GrPoint* translate) { - - GrDrawTarget* target = this->prepareToDraw(paint, kUnbuffered_DrawCategory); - GrPathRenderer* pr = this->getPathRenderer(target, path, fill); - - if (!IsFillInverted(fill) && // will be relaxed soon - !pr->supportsAA(target, path, fill) && - this->doOffscreenAA(target, paint, kHairLine_PathFill == fill)) { - - OffscreenRecord record; - bool needsStencil = pr->requiresStencilPass(target, path, fill); - - // compute bounds as intersection of rt size, clip, and path - GrIRect bound = SkIRect::MakeWH(target->getRenderTarget()->width(), - target->getRenderTarget()->height()); - if (target->getClip().hasConservativeBounds()) { - GrIRect clipIBounds; - target->getClip().getConservativeBounds().roundOut(&clipIBounds); - if (!bound.intersect(clipIBounds)) { - return; - } - } - - GrRect pathBounds = path.getBounds(); - GrIRect pathIBounds; - if (!pathBounds.isEmpty()) { - if (NULL != translate) { - pathBounds.offset(*translate); - } - target->getViewMatrix().mapRect(&pathBounds, pathBounds); - pathBounds.roundOut(&pathIBounds); - if (!bound.intersect(pathIBounds)) { - return; - } - } - - // for now, abort antialiasing if our bounds are too big, so we don't - // hit the FBO size limit - if (pathIBounds.width() > GR_MAX_OFFSCREEN_AA_DIM || - pathIBounds.height() > GR_MAX_OFFSCREEN_AA_DIM) { - goto NO_AA; - } - - if (this->setupOffscreenAAPass1(target, needsStencil, bound, &record)) { - pr->drawPath(target, 0, path, fill, translate); - this->offscreenAAPass2(target, paint, bound, &record); - return; - } - } - -// we can fall out of the AA section for some reasons, and land here -NO_AA: - GrDrawTarget::StageBitfield enabledStages = paint.getActiveStageMask(); - - pr->drawPath(target, enabledStages, path, fill, translate); -} - -//////////////////////////////////////////////////////////////////////////////// - -void GrContext::flush(int flagsBitfield) { - if (kDiscard_FlushBit & flagsBitfield) { - fDrawBuffer->reset(); - } else { - flushDrawBuffer(); - } - - if (kForceCurrentRenderTarget_FlushBit & flagsBitfield) { - fGpu->forceRenderTargetFlush(); - } -} - -void GrContext::flushText() { - if (kText_DrawCategory == fLastDrawCategory) { - flushDrawBuffer(); - } -} - -void GrContext::flushDrawBuffer() { -#if BATCH_RECT_TO_RECT || DEFER_TEXT_RENDERING - if (fDrawBuffer) { - fDrawBuffer->playback(fGpu); - fDrawBuffer->reset(); - } -#endif -} - -bool GrContext::readTexturePixels(GrTexture* texture, - int left, int top, int width, int height, - GrPixelConfig config, void* buffer) { - - // TODO: code read pixels for textures that aren't rendertargets - - this->flush(); - GrRenderTarget* target = texture->asRenderTarget(); - if (NULL != target) { - return fGpu->readPixels(target, - left, top, width, height, - config, buffer); - } else { - return false; - } -} - -bool GrContext::readRenderTargetPixels(GrRenderTarget* target, - int left, int top, int width, int height, - GrPixelConfig config, void* buffer) { - uint32_t flushFlags = 0; - if (NULL == target) { - flushFlags |= GrContext::kForceCurrentRenderTarget_FlushBit; - } - - this->flush(flushFlags); - return fGpu->readPixels(target, - left, top, width, height, - config, buffer); -} - -void GrContext::writePixels(int left, int top, int width, int height, - GrPixelConfig config, const void* buffer, - size_t stride) { - - // TODO: when underlying api has a direct way to do this we should use it - // (e.g. glDrawPixels on desktop GL). - - const GrTextureDesc desc = { - kNone_GrTextureFlags, kNone_GrAALevel, width, height, config - }; - GrTexture* texture = fGpu->createTexture(desc, buffer, stride); - if (NULL == texture) { - return; - } - - this->flush(true); - - GrAutoUnref aur(texture); - GrDrawTarget::AutoStateRestore asr(fGpu); - - GrMatrix matrix; - matrix.setTranslate(GrIntToScalar(left), GrIntToScalar(top)); - fGpu->setViewMatrix(matrix); - - fGpu->setColorFilter(0, SkXfermode::kDst_Mode); - fGpu->disableState(GrDrawTarget::kClip_StateBit); - fGpu->setAlpha(0xFF); - fGpu->setBlendFunc(kOne_BlendCoeff, - kZero_BlendCoeff); - fGpu->setTexture(0, texture); - - GrSamplerState sampler; - sampler.setClampNoFilter(); - matrix.setScale(GR_Scalar1 / width, GR_Scalar1 / height); - sampler.setMatrix(matrix); - fGpu->setSamplerState(0, sampler); - - GrVertexLayout layout = GrDrawTarget::StagePosAsTexCoordVertexLayoutBit(0); - static const int VCOUNT = 4; - - GrDrawTarget::AutoReleaseGeometry geo(fGpu, layout, VCOUNT, 0); - if (!geo.succeeded()) { - return; - } - ((GrPoint*)geo.vertices())->setIRectFan(0, 0, width, height); - fGpu->drawNonIndexed(kTriangleFan_PrimitiveType, 0, VCOUNT); -} -//////////////////////////////////////////////////////////////////////////////// - -void GrContext::SetPaint(const GrPaint& paint, GrDrawTarget* target) { - - for (int i = 0; i < GrPaint::kMaxTextures; ++i) { - int s = i + GrPaint::kFirstTextureStage; - target->setTexture(s, paint.getTexture(i)); - target->setSamplerState(s, *paint.getTextureSampler(i)); - } - - target->setFirstCoverageStage(GrPaint::kFirstMaskStage); - - for (int i = 0; i < GrPaint::kMaxMasks; ++i) { - int s = i + GrPaint::kFirstMaskStage; - target->setTexture(s, paint.getMask(i)); - target->setSamplerState(s, *paint.getMaskSampler(i)); - } - - target->setColor(paint.fColor); - - if (paint.fDither) { - target->enableState(GrDrawTarget::kDither_StateBit); - } else { - target->disableState(GrDrawTarget::kDither_StateBit); - } - if (paint.fAntiAlias) { - target->enableState(GrDrawTarget::kAntialias_StateBit); - } else { - target->disableState(GrDrawTarget::kAntialias_StateBit); - } - target->setBlendFunc(paint.fSrcBlendCoeff, paint.fDstBlendCoeff); - target->setColorFilter(paint.fColorFilterColor, paint.fColorFilterXfermode); -} - -GrDrawTarget* GrContext::prepareToDraw(const GrPaint& paint, - DrawCategory category) { - if (category != fLastDrawCategory) { - flushDrawBuffer(); - fLastDrawCategory = category; - } - SetPaint(paint, fGpu); - GrDrawTarget* target = fGpu; - switch (category) { - case kText_DrawCategory: -#if DEFER_TEXT_RENDERING - target = fDrawBuffer; - fDrawBuffer->initializeDrawStateAndClip(*fGpu); -#else - target = fGpu; -#endif - break; - case kUnbuffered_DrawCategory: - target = fGpu; - break; - case kBuffered_DrawCategory: - target = fDrawBuffer; - fDrawBuffer->initializeDrawStateAndClip(*fGpu); - break; - } - return target; -} - -//////////////////////////////////////////////////////////////////////////////// - -void GrContext::setRenderTarget(GrRenderTarget* target) { - this->flush(false); - fGpu->setRenderTarget(target); -} - -GrRenderTarget* GrContext::getRenderTarget() { - return fGpu->getRenderTarget(); -} - -const GrRenderTarget* GrContext::getRenderTarget() const { - return fGpu->getRenderTarget(); -} - -const GrMatrix& GrContext::getMatrix() const { - return fGpu->getViewMatrix(); -} - -void GrContext::setMatrix(const GrMatrix& m) { - fGpu->setViewMatrix(m); -} - -void GrContext::concatMatrix(const GrMatrix& m) const { - fGpu->preConcatViewMatrix(m); -} - -static inline intptr_t setOrClear(intptr_t bits, int shift, intptr_t pred) { - intptr_t mask = 1 << shift; - if (pred) { - bits |= mask; - } else { - bits &= ~mask; - } - return bits; -} - -void GrContext::resetStats() { - fGpu->resetStats(); -} - -const GrGpuStats& GrContext::getStats() const { - return fGpu->getStats(); -} - -void GrContext::printStats() const { - fGpu->printStats(); -} - -GrContext::GrContext(GrGpu* gpu) : - fDefaultPathRenderer(gpu->supportsTwoSidedStencil(), - gpu->supportsStencilWrapOps()) { - - fGpu = gpu; - fGpu->ref(); - fGpu->setContext(this); - - fCustomPathRenderer = GrPathRenderer::CreatePathRenderer(); - fGpu->setClipPathRenderer(fCustomPathRenderer); - - fTextureCache = new GrTextureCache(MAX_TEXTURE_CACHE_COUNT, - MAX_TEXTURE_CACHE_BYTES); - fFontCache = new GrFontCache(fGpu); - - fLastDrawCategory = kUnbuffered_DrawCategory; - - fDrawBuffer = NULL; - fDrawBufferVBAllocPool = NULL; - fDrawBufferIBAllocPool = NULL; - - fAAFillRectIndexBuffer = NULL; - fAAStrokeRectIndexBuffer = NULL; - - this->setupDrawBuffer(); -} - -void GrContext::setupDrawBuffer() { - - GrAssert(NULL == fDrawBuffer); - GrAssert(NULL == fDrawBufferVBAllocPool); - GrAssert(NULL == fDrawBufferIBAllocPool); - -#if DEFER_TEXT_RENDERING || BATCH_RECT_TO_RECT - fDrawBufferVBAllocPool = - new GrVertexBufferAllocPool(fGpu, false, - DRAW_BUFFER_VBPOOL_BUFFER_SIZE, - DRAW_BUFFER_VBPOOL_PREALLOC_BUFFERS); - fDrawBufferIBAllocPool = - new GrIndexBufferAllocPool(fGpu, false, - DRAW_BUFFER_IBPOOL_BUFFER_SIZE, - DRAW_BUFFER_IBPOOL_PREALLOC_BUFFERS); - - fDrawBuffer = new GrInOrderDrawBuffer(fDrawBufferVBAllocPool, - fDrawBufferIBAllocPool); -#endif - -#if BATCH_RECT_TO_RECT - fDrawBuffer->setQuadIndexBuffer(this->getQuadIndexBuffer()); -#endif -} - -GrDrawTarget* GrContext::getTextTarget(const GrPaint& paint) { - GrDrawTarget* target; -#if DEFER_TEXT_RENDERING - target = prepareToDraw(paint, kText_DrawCategory); -#else - target = prepareToDraw(paint, kUnbuffered_DrawCategory); -#endif - SetPaint(paint, target); - return target; -} - -const GrIndexBuffer* GrContext::getQuadIndexBuffer() const { - return fGpu->getQuadIndexBuffer(); -} - -GrPathRenderer* GrContext::getPathRenderer(const GrDrawTarget* target, - const GrPath& path, - GrPathFill fill) { - if (NULL != fCustomPathRenderer && - fCustomPathRenderer->canDrawPath(target, path, fill)) { - return fCustomPathRenderer; - } else { - GrAssert(fDefaultPathRenderer.canDrawPath(target, path, fill)); - return &fDefaultPathRenderer; - } -} - |