1ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
2ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com/*
3ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * Copyright 2010 Google Inc.
4ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com *
5ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * Use of this source code is governed by a BSD-style license that can be
6ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * found in the LICENSE file.
7ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com */
8ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
9ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com
10ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com#include "GrGpu.h"
11558a75bcb323c03dd7482555c7214062a363276fbsalomon@google.com
1281c3f8de1cbb93a8b99d730a75ab16d864612e95bsalomon@google.com#include "GrBufferAllocPool.h"
13558a75bcb323c03dd7482555c7214062a363276fbsalomon@google.com#include "GrContext.h"
14c26d94fd7dc0b00cd6d0e42d28285f4a38aff021bsalomon@google.com#include "GrDrawTargetCaps.h"
15ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com#include "GrIndexBuffer.h"
16dd182cbca60a7f0003330c01dfc64f69f56aea90tomhudson@google.com#include "GrStencilBuffer.h"
1781c3f8de1cbb93a8b99d730a75ab16d864612e95bsalomon@google.com#include "GrVertexBuffer.h"
181c13c9668a889e56a0c85b51b9f28139c25b76ffbsalomon@google.com
191c13c9668a889e56a0c85b51b9f28139c25b76ffbsalomon@google.com// probably makes no sense for this to be less than a page
20ee435122d7dcb9cd4be4524004b0de282c42848bbsalomon@google.comstatic const size_t VERTEX_POOL_VB_SIZE = 1 << 18;
21ee435122d7dcb9cd4be4524004b0de282c42848bbsalomon@google.comstatic const int VERTEX_POOL_VB_COUNT = 4;
2225fd36c7efc0287b6a2a82463eacaeaf91ca07b9bsalomon@google.comstatic const size_t INDEX_POOL_IB_SIZE = 1 << 16;
2325fd36c7efc0287b6a2a82463eacaeaf91ca07b9bsalomon@google.comstatic const int INDEX_POOL_IB_COUNT = 4;
24ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
25d302f1401b3c9aea094804bad4e76de98782cfe8bsalomon@google.com////////////////////////////////////////////////////////////////////////////////
26ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
2725fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com#define DEBUG_INVAL_BUFFER    0xdeadcafe
2825fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com#define DEBUG_INVAL_START_IDX -1
2925fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com
306e4e65066a7c0dbc9bfbfe4b8f5d49c3d8a79b59bsalomon@google.comGrGpu::GrGpu(GrContext* context)
316e4e65066a7c0dbc9bfbfe4b8f5d49c3d8a79b59bsalomon@google.com    : GrDrawTarget(context)
32979432ba2621b617f5e85a9ff48c6b6cd1504a0dbsalomon@google.com    , fResetTimestamp(kExpiredTimestamp+1)
330a208a117b2d7f2c2231aa357f1db4864dbdcba3bsalomon@google.com    , fResetBits(kAll_GrBackendState)
348fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.com    , fVertexPool(NULL)
358fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.com    , fIndexPool(NULL)
3625fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    , fVertexPoolUseCnt(0)
3725fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    , fIndexPoolUseCnt(0)
380a208a117b2d7f2c2231aa357f1db4864dbdcba3bsalomon@google.com    , fQuadIndexBuffer(NULL) {
39669fdc4ed8ed461a141cb97d0afdd9ef72a82be1bsalomon@google.com
405d8d18651a64f62dbb8881794e23f53bf22c9a23robertphillips@google.com    fClipMaskManager.setGpu(this);
415d8d18651a64f62dbb8881794e23f53bf22c9a23robertphillips@google.com
4225fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    fGeomPoolStateStack.push_back();
43515dcd36032997ce335daa0163c6d67e851bcad1commit-bot@chromium.org#ifdef SK_DEBUG
4425fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    GeometryPoolState& poolState = fGeomPoolStateStack.back();
4525fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    poolState.fPoolVertexBuffer = (GrVertexBuffer*)DEBUG_INVAL_BUFFER;
4625fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    poolState.fPoolStartVertex = DEBUG_INVAL_START_IDX;
4725fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    poolState.fPoolIndexBuffer = (GrIndexBuffer*)DEBUG_INVAL_BUFFER;
4825fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    poolState.fPoolStartIndex = DEBUG_INVAL_START_IDX;
4925fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com#endif
50ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com}
51ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
52ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.comGrGpu::~GrGpu() {
53558a75bcb323c03dd7482555c7214062a363276fbsalomon@google.com    this->releaseResources();
548fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.com}
558fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.com
568fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.comvoid GrGpu::abandonResources() {
578fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.com
58f105b109264f71dfb0bfd9977e6a5dd0a5a12f57robertphillips@google.com    fClipMaskManager.releaseResources();
59f105b109264f71dfb0bfd9977e6a5dd0a5a12f57robertphillips@google.com
60089a780c3355129eefc942246534bc1f126b8ccbcommit-bot@chromium.org    while (NULL != fObjectList.head()) {
61089a780c3355129eefc942246534bc1f126b8ccbcommit-bot@chromium.org        fObjectList.head()->abandon();
628fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.com    }
638fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.com
64089a780c3355129eefc942246534bc1f126b8ccbcommit-bot@chromium.org    SkASSERT(NULL == fQuadIndexBuffer || fQuadIndexBuffer->wasDestroyed());
65a4de8c257ea0be8ff7081f645249b6afe5c48e7ecommit-bot@chromium.org    SkSafeSetNull(fQuadIndexBuffer);
668fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.com    delete fVertexPool;
678fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.com    fVertexPool = NULL;
688fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.com    delete fIndexPool;
698fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.com    fIndexPool = NULL;
708fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.com}
718fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.com
728fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.comvoid GrGpu::releaseResources() {
738fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.com
74f105b109264f71dfb0bfd9977e6a5dd0a5a12f57robertphillips@google.com    fClipMaskManager.releaseResources();
75f105b109264f71dfb0bfd9977e6a5dd0a5a12f57robertphillips@google.com
76089a780c3355129eefc942246534bc1f126b8ccbcommit-bot@chromium.org    while (NULL != fObjectList.head()) {
77089a780c3355129eefc942246534bc1f126b8ccbcommit-bot@chromium.org        fObjectList.head()->release();
788fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.com    }
798fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.com
80089a780c3355129eefc942246534bc1f126b8ccbcommit-bot@chromium.org    SkASSERT(NULL == fQuadIndexBuffer || fQuadIndexBuffer->wasDestroyed());
81a4de8c257ea0be8ff7081f645249b6afe5c48e7ecommit-bot@chromium.org    SkSafeSetNull(fQuadIndexBuffer);
821c13c9668a889e56a0c85b51b9f28139c25b76ffbsalomon@google.com    delete fVertexPool;
838fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.com    fVertexPool = NULL;
841c13c9668a889e56a0c85b51b9f28139c25b76ffbsalomon@google.com    delete fIndexPool;
858fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.com    fIndexPool = NULL;
868fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.com}
878fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.com
88089a780c3355129eefc942246534bc1f126b8ccbcommit-bot@chromium.orgvoid GrGpu::insertObject(GrGpuObject* object) {
89089a780c3355129eefc942246534bc1f126b8ccbcommit-bot@chromium.org    SkASSERT(NULL != object);
90089a780c3355129eefc942246534bc1f126b8ccbcommit-bot@chromium.org    SkASSERT(this == object->getGpu());
918fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.com
92089a780c3355129eefc942246534bc1f126b8ccbcommit-bot@chromium.org    fObjectList.addToHead(object);
93ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com}
94ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
95089a780c3355129eefc942246534bc1f126b8ccbcommit-bot@chromium.orgvoid GrGpu::removeObject(GrGpuObject* object) {
96089a780c3355129eefc942246534bc1f126b8ccbcommit-bot@chromium.org    SkASSERT(NULL != object);
97089a780c3355129eefc942246534bc1f126b8ccbcommit-bot@chromium.org    SkASSERT(this == object->getGpu());
989474ed06176fe24c77091b0d75f35442e851073frobertphillips@google.com
99089a780c3355129eefc942246534bc1f126b8ccbcommit-bot@chromium.org    fObjectList.remove(object);
100ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com}
101ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
1028fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.com
103ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.comvoid GrGpu::unimpl(const char msg[]) {
104515dcd36032997ce335daa0163c6d67e851bcad1commit-bot@chromium.org#ifdef SK_DEBUG
1057d34d2eecc40d150d867e37d5160a1bc3cfccbdebsalomon@google.com    GrPrintf("--- GrGpu unimplemented(\"%s\")\n", msg);
1067d34d2eecc40d150d867e37d5160a1bc3cfccbdebsalomon@google.com#endif
107ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com}
108ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
109d302f1401b3c9aea094804bad4e76de98782cfe8bsalomon@google.com////////////////////////////////////////////////////////////////////////////////
110ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
111fea37b5e532dfe776269253afb9951e763c3b205bsalomon@google.comGrTexture* GrGpu::createTexture(const GrTextureDesc& desc,
112a7f84e150cb9e821267a8ca9e59c1ae9a3cfa300bsalomon@google.com                                const void* srcData, size_t rowBytes) {
1139c0e629c64c0fa93ac9bf5c2eaa1821370a6fbe5krajcevski    if (!this->caps()->isConfigTexturable(desc.fConfig)) {
114d3eb336d56b2ad989229c8fb21ea20f5a7b14a32robertphillips@google.com        return NULL;
115d3eb336d56b2ad989229c8fb21ea20f5a7b14a32robertphillips@google.com    }
1169c0e629c64c0fa93ac9bf5c2eaa1821370a6fbe5krajcevski
1176b7938f9cb250086a7c6325cf31576f894ca4a1bcommit-bot@chromium.org    if ((desc.fFlags & kRenderTarget_GrTextureFlagBit) &&
1186b7938f9cb250086a7c6325cf31576f894ca4a1bcommit-bot@chromium.org        !this->caps()->isConfigRenderable(desc.fConfig, desc.fSampleCnt > 0)) {
1196b7938f9cb250086a7c6325cf31576f894ca4a1bcommit-bot@chromium.org        return NULL;
1206b7938f9cb250086a7c6325cf31576f894ca4a1bcommit-bot@chromium.org    }
121d3eb336d56b2ad989229c8fb21ea20f5a7b14a32robertphillips@google.com
1229c0e629c64c0fa93ac9bf5c2eaa1821370a6fbe5krajcevski    GrTexture *tex = NULL;
1239c0e629c64c0fa93ac9bf5c2eaa1821370a6fbe5krajcevski    if (GrPixelConfigIsCompressed(desc.fConfig)) {
1249c0e629c64c0fa93ac9bf5c2eaa1821370a6fbe5krajcevski        // We shouldn't be rendering into this
1259c0e629c64c0fa93ac9bf5c2eaa1821370a6fbe5krajcevski        SkASSERT((desc.fFlags & kRenderTarget_GrTextureFlagBit) == 0);
1269c0e629c64c0fa93ac9bf5c2eaa1821370a6fbe5krajcevski
1279c0e629c64c0fa93ac9bf5c2eaa1821370a6fbe5krajcevski        if (!this->caps()->npotTextureTileSupport() &&
128f9dae780c2c46a1f08adbbe8de2faaba091254d4tfarina            (!SkIsPow2(desc.fWidth) || !SkIsPow2(desc.fHeight))) {
12981c3f8de1cbb93a8b99d730a75ab16d864612e95bsalomon@google.com            return NULL;
13081c3f8de1cbb93a8b99d730a75ab16d864612e95bsalomon@google.com        }
131f9dae780c2c46a1f08adbbe8de2faaba091254d4tfarina
1329c0e629c64c0fa93ac9bf5c2eaa1821370a6fbe5krajcevski        this->handleDirtyContext();
1339c0e629c64c0fa93ac9bf5c2eaa1821370a6fbe5krajcevski        tex = this->onCreateCompressedTexture(desc, srcData);
1349c0e629c64c0fa93ac9bf5c2eaa1821370a6fbe5krajcevski    } else {
1359c0e629c64c0fa93ac9bf5c2eaa1821370a6fbe5krajcevski        this->handleDirtyContext();
1369c0e629c64c0fa93ac9bf5c2eaa1821370a6fbe5krajcevski        tex = this->onCreateTexture(desc, srcData, rowBytes);
1379c0e629c64c0fa93ac9bf5c2eaa1821370a6fbe5krajcevski        if (NULL != tex &&
1389c0e629c64c0fa93ac9bf5c2eaa1821370a6fbe5krajcevski            (kRenderTarget_GrTextureFlagBit & desc.fFlags) &&
1399c0e629c64c0fa93ac9bf5c2eaa1821370a6fbe5krajcevski            !(kNoStencil_GrTextureFlagBit & desc.fFlags)) {
1409c0e629c64c0fa93ac9bf5c2eaa1821370a6fbe5krajcevski            SkASSERT(NULL != tex->asRenderTarget());
1419c0e629c64c0fa93ac9bf5c2eaa1821370a6fbe5krajcevski            // TODO: defer this and attach dynamically
1429c0e629c64c0fa93ac9bf5c2eaa1821370a6fbe5krajcevski            if (!this->attachStencilBufferToRenderTarget(tex->asRenderTarget())) {
1439c0e629c64c0fa93ac9bf5c2eaa1821370a6fbe5krajcevski                tex->unref();
1449c0e629c64c0fa93ac9bf5c2eaa1821370a6fbe5krajcevski                return NULL;
1459c0e629c64c0fa93ac9bf5c2eaa1821370a6fbe5krajcevski            }
1469c0e629c64c0fa93ac9bf5c2eaa1821370a6fbe5krajcevski        }
14781c3f8de1cbb93a8b99d730a75ab16d864612e95bsalomon@google.com    }
14881c3f8de1cbb93a8b99d730a75ab16d864612e95bsalomon@google.com    return tex;
14981c3f8de1cbb93a8b99d730a75ab16d864612e95bsalomon@google.com}
15081c3f8de1cbb93a8b99d730a75ab16d864612e95bsalomon@google.com
15181c3f8de1cbb93a8b99d730a75ab16d864612e95bsalomon@google.combool GrGpu::attachStencilBufferToRenderTarget(GrRenderTarget* rt) {
152f6de475e5cbd143f348ff7738919e397b7fe7f57tfarina@chromium.org    SkASSERT(NULL == rt->getStencilBuffer());
153d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com    GrStencilBuffer* sb =
1549fbcad0f00d7098574cf3394a812c9d845c9cc5brobertphillips@google.com        this->getContext()->findStencilBuffer(rt->width(),
1559fbcad0f00d7098574cf3394a812c9d845c9cc5brobertphillips@google.com                                              rt->height(),
1569fbcad0f00d7098574cf3394a812c9d845c9cc5brobertphillips@google.com                                              rt->numSamples());
157558a75bcb323c03dd7482555c7214062a363276fbsalomon@google.com    if (NULL != sb) {
158558a75bcb323c03dd7482555c7214062a363276fbsalomon@google.com        rt->setStencilBuffer(sb);
159558a75bcb323c03dd7482555c7214062a363276fbsalomon@google.com        bool attached = this->attachStencilBufferToRenderTarget(sb, rt);
160558a75bcb323c03dd7482555c7214062a363276fbsalomon@google.com        if (!attached) {
161558a75bcb323c03dd7482555c7214062a363276fbsalomon@google.com            rt->setStencilBuffer(NULL);
162558a75bcb323c03dd7482555c7214062a363276fbsalomon@google.com        }
163558a75bcb323c03dd7482555c7214062a363276fbsalomon@google.com        return attached;
164558a75bcb323c03dd7482555c7214062a363276fbsalomon@google.com    }
1659962108c400dadcae913614e8a5ab781780981d8bsalomon@google.com    if (this->createStencilBufferForRenderTarget(rt,
1669962108c400dadcae913614e8a5ab781780981d8bsalomon@google.com                                                 rt->width(), rt->height())) {
167edc177df618a61e35d4f07c49d5dcb5de9c7afb1bsalomon@google.com        // Right now we're clearing the stencil buffer here after it is
168edc177df618a61e35d4f07c49d5dcb5de9c7afb1bsalomon@google.com        // attached to an RT for the first time. When we start matching
169edc177df618a61e35d4f07c49d5dcb5de9c7afb1bsalomon@google.com        // stencil buffers with smaller color targets this will no longer
170edc177df618a61e35d4f07c49d5dcb5de9c7afb1bsalomon@google.com        // be correct because it won't be guaranteed to clear the entire
171edc177df618a61e35d4f07c49d5dcb5de9c7afb1bsalomon@google.com        // sb.
172edc177df618a61e35d4f07c49d5dcb5de9c7afb1bsalomon@google.com        // We used to clear down in the GL subclass using a special purpose
173edc177df618a61e35d4f07c49d5dcb5de9c7afb1bsalomon@google.com        // FBO. But iOS doesn't allow a stencil-only FBO. It reports unsupported
174edc177df618a61e35d4f07c49d5dcb5de9c7afb1bsalomon@google.com        // FBO status.
1758f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        GrDrawState::AutoRenderTargetRestore artr(this->drawState(), rt);
176edc177df618a61e35d4f07c49d5dcb5de9c7afb1bsalomon@google.com        this->clearStencil();
177558a75bcb323c03dd7482555c7214062a363276fbsalomon@google.com        return true;
178558a75bcb323c03dd7482555c7214062a363276fbsalomon@google.com    } else {
179558a75bcb323c03dd7482555c7214062a363276fbsalomon@google.com        return false;
180edc177df618a61e35d4f07c49d5dcb5de9c7afb1bsalomon@google.com    }
181a7f84e150cb9e821267a8ca9e59c1ae9a3cfa300bsalomon@google.com}
182a7f84e150cb9e821267a8ca9e59c1ae9a3cfa300bsalomon@google.com
18316e3ddea6a80972aced04b21b1d66377fa95e7c7bsalomon@google.comGrTexture* GrGpu::wrapBackendTexture(const GrBackendTextureDesc& desc) {
184e269f210bdae0288643afaf8a579b22d3f6d5bebbsalomon@google.com    this->handleDirtyContext();
18516e3ddea6a80972aced04b21b1d66377fa95e7c7bsalomon@google.com    GrTexture* tex = this->onWrapBackendTexture(desc);
186a14dd6db824bb391969181ae4a6bf89f57088390bsalomon@google.com    if (NULL == tex) {
187a14dd6db824bb391969181ae4a6bf89f57088390bsalomon@google.com        return NULL;
188a14dd6db824bb391969181ae4a6bf89f57088390bsalomon@google.com    }
189e269f210bdae0288643afaf8a579b22d3f6d5bebbsalomon@google.com    // TODO: defer this and attach dynamically
190e269f210bdae0288643afaf8a579b22d3f6d5bebbsalomon@google.com    GrRenderTarget* tgt = tex->asRenderTarget();
191e269f210bdae0288643afaf8a579b22d3f6d5bebbsalomon@google.com    if (NULL != tgt &&
192e269f210bdae0288643afaf8a579b22d3f6d5bebbsalomon@google.com        !this->attachStencilBufferToRenderTarget(tgt)) {
193e269f210bdae0288643afaf8a579b22d3f6d5bebbsalomon@google.com        tex->unref();
194e269f210bdae0288643afaf8a579b22d3f6d5bebbsalomon@google.com        return NULL;
195e269f210bdae0288643afaf8a579b22d3f6d5bebbsalomon@google.com    } else {
196e269f210bdae0288643afaf8a579b22d3f6d5bebbsalomon@google.com        return tex;
197e269f210bdae0288643afaf8a579b22d3f6d5bebbsalomon@google.com    }
198e269f210bdae0288643afaf8a579b22d3f6d5bebbsalomon@google.com}
199e269f210bdae0288643afaf8a579b22d3f6d5bebbsalomon@google.com
20016e3ddea6a80972aced04b21b1d66377fa95e7c7bsalomon@google.comGrRenderTarget* GrGpu::wrapBackendRenderTarget(const GrBackendRenderTargetDesc& desc) {
201e269f210bdae0288643afaf8a579b22d3f6d5bebbsalomon@google.com    this->handleDirtyContext();
20216e3ddea6a80972aced04b21b1d66377fa95e7c7bsalomon@google.com    return this->onWrapBackendRenderTarget(desc);
203e269f210bdae0288643afaf8a579b22d3f6d5bebbsalomon@google.com}
204e269f210bdae0288643afaf8a579b22d3f6d5bebbsalomon@google.com
205adacc7067ad617cdc7bbef39192ca80f4b4d27f9robertphillips@google.comGrVertexBuffer* GrGpu::createVertexBuffer(size_t size, bool dynamic) {
206a7f84e150cb9e821267a8ca9e59c1ae9a3cfa300bsalomon@google.com    this->handleDirtyContext();
207bcdbbe61e1a3f89545b2c1461164f0f8bf5f0797bsalomon@google.com    return this->onCreateVertexBuffer(size, dynamic);
208a7f84e150cb9e821267a8ca9e59c1ae9a3cfa300bsalomon@google.com}
209a7f84e150cb9e821267a8ca9e59c1ae9a3cfa300bsalomon@google.com
210adacc7067ad617cdc7bbef39192ca80f4b4d27f9robertphillips@google.comGrIndexBuffer* GrGpu::createIndexBuffer(size_t size, bool dynamic) {
211a7f84e150cb9e821267a8ca9e59c1ae9a3cfa300bsalomon@google.com    this->handleDirtyContext();
212bcdbbe61e1a3f89545b2c1461164f0f8bf5f0797bsalomon@google.com    return this->onCreateIndexBuffer(size, dynamic);
213a7f84e150cb9e821267a8ca9e59c1ae9a3cfa300bsalomon@google.com}
214a7f84e150cb9e821267a8ca9e59c1ae9a3cfa300bsalomon@google.com
21532184d81629e39809bb9e915286d8fe971a8ed68commit-bot@chromium.orgGrPath* GrGpu::createPath(const SkPath& path, const SkStrokeRec& stroke) {
216c4dc0ad8e252a7e30d19b47d3d0d9f2c69faf854commit-bot@chromium.org    SkASSERT(this->caps()->pathRenderingSupport());
21764aef2bacd1f5c25ffd9347aabd6265c9b60c0f4bsalomon@google.com    this->handleDirtyContext();
21832184d81629e39809bb9e915286d8fe971a8ed68commit-bot@chromium.org    return this->onCreatePath(path, stroke);
21964aef2bacd1f5c25ffd9347aabd6265c9b60c0f4bsalomon@google.com}
22064aef2bacd1f5c25ffd9347aabd6265c9b60c0f4bsalomon@google.com
221fd03d4a829efe2d77a712fd991927c55f59a2ffecommit-bot@chromium.orgvoid GrGpu::clear(const SkIRect* rect,
222d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com                  GrColor color,
22356ce48ade325f6f49acb0da31d6252806e4ed7efrobertphillips@google.com                  bool canIgnoreRect,
224c82a8b7aa4ec19fba508c394920a9e88d3e5bd12robertphillips@google.com                  GrRenderTarget* renderTarget) {
2252e6020634a347626e111592b13ef5030d457bc3fbsalomon@google.com    GrDrawState::AutoRenderTargetRestore art;
2262e6020634a347626e111592b13ef5030d457bc3fbsalomon@google.com    if (NULL != renderTarget) {
2272e6020634a347626e111592b13ef5030d457bc3fbsalomon@google.com        art.set(this->drawState(), renderTarget);
228c82a8b7aa4ec19fba508c394920a9e88d3e5bd12robertphillips@google.com    }
2298f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    if (NULL == this->getDrawState().getRenderTarget()) {
230f6de475e5cbd143f348ff7738919e397b7fe7f57tfarina@chromium.org        SkASSERT(0);
2310ba52fcf93d52a3f230d1f185eea0c8719c176fbbsalomon@google.com        return;
2320ba52fcf93d52a3f230d1f185eea0c8719c176fbbsalomon@google.com    }
233a7f84e150cb9e821267a8ca9e59c1ae9a3cfa300bsalomon@google.com    this->handleDirtyContext();
23456ce48ade325f6f49acb0da31d6252806e4ed7efrobertphillips@google.com    this->onClear(rect, color, canIgnoreRect);
235a7f84e150cb9e821267a8ca9e59c1ae9a3cfa300bsalomon@google.com}
236a7f84e150cb9e821267a8ca9e59c1ae9a3cfa300bsalomon@google.com
237669fdc4ed8ed461a141cb97d0afdd9ef72a82be1bsalomon@google.combool GrGpu::readPixels(GrRenderTarget* target,
238669fdc4ed8ed461a141cb97d0afdd9ef72a82be1bsalomon@google.com                       int left, int top, int width, int height,
239c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com                       GrPixelConfig config, void* buffer,
2403cb406bb88f5aa09cf9f5a9554b4b1314cf1a2eesenorblanco@chromium.org                       size_t rowBytes) {
241a7f84e150cb9e821267a8ca9e59c1ae9a3cfa300bsalomon@google.com    this->handleDirtyContext();
242c69809745e6496564639e42ef998ad39adf7dfb8bsalomon@google.com    return this->onReadPixels(target, left, top, width, height,
2433cb406bb88f5aa09cf9f5a9554b4b1314cf1a2eesenorblanco@chromium.org                              config, buffer, rowBytes);
244a7f84e150cb9e821267a8ca9e59c1ae9a3cfa300bsalomon@google.com}
245a7f84e150cb9e821267a8ca9e59c1ae9a3cfa300bsalomon@google.com
2469c68058b679aee81e6e0158e7fcbfb5d8479c91absalomon@google.combool GrGpu::writeTexturePixels(GrTexture* texture,
2476f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com                               int left, int top, int width, int height,
2486f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com                               GrPixelConfig config, const void* buffer,
2496f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com                               size_t rowBytes) {
2506f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com    this->handleDirtyContext();
2519c68058b679aee81e6e0158e7fcbfb5d8479c91absalomon@google.com    return this->onWriteTexturePixels(texture, left, top, width, height,
2529c68058b679aee81e6e0158e7fcbfb5d8479c91absalomon@google.com                                      config, buffer, rowBytes);
2536f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com}
2546f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com
25575f9f25d8bf2adc0494f9afbbd5965809ee13acabsalomon@google.comvoid GrGpu::resolveRenderTarget(GrRenderTarget* target) {
256f6de475e5cbd143f348ff7738919e397b7fe7f57tfarina@chromium.org    SkASSERT(target);
25775f9f25d8bf2adc0494f9afbbd5965809ee13acabsalomon@google.com    this->handleDirtyContext();
25875f9f25d8bf2adc0494f9afbbd5965809ee13acabsalomon@google.com    this->onResolveRenderTarget(target);
25975f9f25d8bf2adc0494f9afbbd5965809ee13acabsalomon@google.com}
26075f9f25d8bf2adc0494f9afbbd5965809ee13acabsalomon@google.com
261c4dc0ad8e252a7e30d19b47d3d0d9f2c69faf854commit-bot@chromium.orgstatic const GrStencilSettings& winding_path_stencil_settings() {
262c4dc0ad8e252a7e30d19b47d3d0d9f2c69faf854commit-bot@chromium.org    GR_STATIC_CONST_SAME_STENCIL_STRUCT(gSettings,
263c4dc0ad8e252a7e30d19b47d3d0d9f2c69faf854commit-bot@chromium.org        kIncClamp_StencilOp,
264c4dc0ad8e252a7e30d19b47d3d0d9f2c69faf854commit-bot@chromium.org        kIncClamp_StencilOp,
265c4dc0ad8e252a7e30d19b47d3d0d9f2c69faf854commit-bot@chromium.org        kAlwaysIfInClip_StencilFunc,
266c4dc0ad8e252a7e30d19b47d3d0d9f2c69faf854commit-bot@chromium.org        0xFFFF, 0xFFFF, 0xFFFF);
267c4dc0ad8e252a7e30d19b47d3d0d9f2c69faf854commit-bot@chromium.org    return *GR_CONST_STENCIL_SETTINGS_PTR_FROM_STRUCT_PTR(&gSettings);
268c4dc0ad8e252a7e30d19b47d3d0d9f2c69faf854commit-bot@chromium.org}
269c4dc0ad8e252a7e30d19b47d3d0d9f2c69faf854commit-bot@chromium.org
270c4dc0ad8e252a7e30d19b47d3d0d9f2c69faf854commit-bot@chromium.orgstatic const GrStencilSettings& even_odd_path_stencil_settings() {
271c4dc0ad8e252a7e30d19b47d3d0d9f2c69faf854commit-bot@chromium.org    GR_STATIC_CONST_SAME_STENCIL_STRUCT(gSettings,
272c4dc0ad8e252a7e30d19b47d3d0d9f2c69faf854commit-bot@chromium.org        kInvert_StencilOp,
273c4dc0ad8e252a7e30d19b47d3d0d9f2c69faf854commit-bot@chromium.org        kInvert_StencilOp,
274c4dc0ad8e252a7e30d19b47d3d0d9f2c69faf854commit-bot@chromium.org        kAlwaysIfInClip_StencilFunc,
275c4dc0ad8e252a7e30d19b47d3d0d9f2c69faf854commit-bot@chromium.org        0xFFFF, 0xFFFF, 0xFFFF);
276c4dc0ad8e252a7e30d19b47d3d0d9f2c69faf854commit-bot@chromium.org    return *GR_CONST_STENCIL_SETTINGS_PTR_FROM_STRUCT_PTR(&gSettings);
277c4dc0ad8e252a7e30d19b47d3d0d9f2c69faf854commit-bot@chromium.org}
278c4dc0ad8e252a7e30d19b47d3d0d9f2c69faf854commit-bot@chromium.org
279c4dc0ad8e252a7e30d19b47d3d0d9f2c69faf854commit-bot@chromium.orgvoid GrGpu::getPathStencilSettingsForFillType(SkPath::FillType fill, GrStencilSettings* outStencilSettings) {
280c4dc0ad8e252a7e30d19b47d3d0d9f2c69faf854commit-bot@chromium.org
281c4dc0ad8e252a7e30d19b47d3d0d9f2c69faf854commit-bot@chromium.org    switch (fill) {
282c4dc0ad8e252a7e30d19b47d3d0d9f2c69faf854commit-bot@chromium.org        default:
28388cb22b6b4816c7a9ca6c5b795965b4606f9eb7bcommit-bot@chromium.org            SkFAIL("Unexpected path fill.");
284c4dc0ad8e252a7e30d19b47d3d0d9f2c69faf854commit-bot@chromium.org            /* fallthrough */;
285c4dc0ad8e252a7e30d19b47d3d0d9f2c69faf854commit-bot@chromium.org        case SkPath::kWinding_FillType:
286c4dc0ad8e252a7e30d19b47d3d0d9f2c69faf854commit-bot@chromium.org        case SkPath::kInverseWinding_FillType:
287c4dc0ad8e252a7e30d19b47d3d0d9f2c69faf854commit-bot@chromium.org            *outStencilSettings = winding_path_stencil_settings();
288c4dc0ad8e252a7e30d19b47d3d0d9f2c69faf854commit-bot@chromium.org            break;
289c4dc0ad8e252a7e30d19b47d3d0d9f2c69faf854commit-bot@chromium.org        case SkPath::kEvenOdd_FillType:
290c4dc0ad8e252a7e30d19b47d3d0d9f2c69faf854commit-bot@chromium.org        case SkPath::kInverseEvenOdd_FillType:
291c4dc0ad8e252a7e30d19b47d3d0d9f2c69faf854commit-bot@chromium.org            *outStencilSettings = even_odd_path_stencil_settings();
292c4dc0ad8e252a7e30d19b47d3d0d9f2c69faf854commit-bot@chromium.org            break;
293c4dc0ad8e252a7e30d19b47d3d0d9f2c69faf854commit-bot@chromium.org    }
294c4dc0ad8e252a7e30d19b47d3d0d9f2c69faf854commit-bot@chromium.org    fClipMaskManager.adjustPathStencilParams(outStencilSettings);
295c4dc0ad8e252a7e30d19b47d3d0d9f2c69faf854commit-bot@chromium.org}
296c4dc0ad8e252a7e30d19b47d3d0d9f2c69faf854commit-bot@chromium.org
29775f9f25d8bf2adc0494f9afbbd5965809ee13acabsalomon@google.com
298a7f84e150cb9e821267a8ca9e59c1ae9a3cfa300bsalomon@google.com////////////////////////////////////////////////////////////////////////////////
299a7f84e150cb9e821267a8ca9e59c1ae9a3cfa300bsalomon@google.com
3001c13c9668a889e56a0c85b51b9f28139c25b76ffbsalomon@google.comstatic const int MAX_QUADS = 1 << 12; // max possible: (1 << 14) - 1;
301ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
3028195f674278e8d785bf57489847b1d05d3c2f7d5reed@google.comGR_STATIC_ASSERT(4 * MAX_QUADS <= 65535);
303ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
3041c13c9668a889e56a0c85b51b9f28139c25b76ffbsalomon@google.comstatic inline void fill_indices(uint16_t* indices, int quadCount) {
305ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    for (int i = 0; i < quadCount; ++i) {
306ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com        indices[6 * i + 0] = 4 * i + 0;
307ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com        indices[6 * i + 1] = 4 * i + 1;
308ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com        indices[6 * i + 2] = 4 * i + 2;
309ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com        indices[6 * i + 3] = 4 * i + 0;
310ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com        indices[6 * i + 4] = 4 * i + 2;
311ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com        indices[6 * i + 5] = 4 * i + 3;
312ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    }
313ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com}
314ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
31586afc2ae27fec84c01eb0e81a32766bdaf67dca8bsalomon@google.comconst GrIndexBuffer* GrGpu::getQuadIndexBuffer() const {
316ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    if (NULL == fQuadIndexBuffer) {
317ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com        static const int SIZE = sizeof(uint16_t) * 6 * MAX_QUADS;
318ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com        GrGpu* me = const_cast<GrGpu*>(this);
319ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com        fQuadIndexBuffer = me->createIndexBuffer(SIZE, false);
320ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com        if (NULL != fQuadIndexBuffer) {
3218341eb76fbc54593e873f5589961e02793e7f15fcommit-bot@chromium.org            uint16_t* indices = (uint16_t*)fQuadIndexBuffer->map();
322ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com            if (NULL != indices) {
3231c13c9668a889e56a0c85b51b9f28139c25b76ffbsalomon@google.com                fill_indices(indices, MAX_QUADS);
3248341eb76fbc54593e873f5589961e02793e7f15fcommit-bot@chromium.org                fQuadIndexBuffer->unmap();
325ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com            } else {
326939ca7ce860c5e80a4fdccc0dba5f7bfa29fef22reed@google.com                indices = (uint16_t*)sk_malloc_throw(SIZE);
3271c13c9668a889e56a0c85b51b9f28139c25b76ffbsalomon@google.com                fill_indices(indices, MAX_QUADS);
328ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com                if (!fQuadIndexBuffer->updateData(indices, SIZE)) {
329ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com                    fQuadIndexBuffer->unref();
330ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com                    fQuadIndexBuffer = NULL;
33188cb22b6b4816c7a9ca6c5b795965b4606f9eb7bcommit-bot@chromium.org                    SkFAIL("Can't get indices into buffer!");
332ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com                }
333939ca7ce860c5e80a4fdccc0dba5f7bfa29fef22reed@google.com                sk_free(indices);
334ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com            }
335ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com        }
336ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    }
337ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
338ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    return fQuadIndexBuffer;
339ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com}
340ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
341d302f1401b3c9aea094804bad4e76de98782cfe8bsalomon@google.com////////////////////////////////////////////////////////////////////////////////
342ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
343eb6879f50a5564eeb981ec5616b55bf685eb76fcbsalomon@google.combool GrGpu::setupClipAndFlushState(DrawType type, const GrDeviceCoordTexture* dstCopy,
3443ae0e6c2b213d45c370846a4d4182a6754ca493ecommit-bot@chromium.org                                   GrDrawState::AutoRestoreEffects* are,
3453ae0e6c2b213d45c370846a4d4182a6754ca493ecommit-bot@chromium.org                                   const SkRect* devBounds) {
3463ae0e6c2b213d45c370846a4d4182a6754ca493ecommit-bot@chromium.org    if (!fClipMaskManager.setupClipping(this->getClip(), are, devBounds)) {
347730ebe5e0058da5fc2c615c042819a82df29e7c0robertphillips@google.com        return false;
348ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    }
349d302f1401b3c9aea094804bad4e76de98782cfe8bsalomon@google.com
35026e18b593ab65e4d92dfbce92579d8bc180d4c2cbsalomon@google.com    if (!this->flushGraphicsState(type, dstCopy)) {
351ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com        return false;
352ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    }
353730ebe5e0058da5fc2c615c042819a82df29e7c0robertphillips@google.com
354ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    return true;
355ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com}
356ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
357d302f1401b3c9aea094804bad4e76de98782cfe8bsalomon@google.com////////////////////////////////////////////////////////////////////////////////
358ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
35925fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.comvoid GrGpu::geometrySourceWillPush() {
36025fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    const GeometrySrcState& geoSrc = this->getGeomSrc();
36125fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    if (kArray_GeometrySrcType == geoSrc.fVertexSrc ||
36225fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com        kReserved_GeometrySrcType == geoSrc.fVertexSrc) {
36325fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com        this->finalizeReservedVertices();
36425fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    }
36525fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    if (kArray_GeometrySrcType == geoSrc.fIndexSrc ||
36625fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com        kReserved_GeometrySrcType == geoSrc.fIndexSrc) {
36725fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com        this->finalizeReservedIndices();
36825fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    }
36925fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    GeometryPoolState& newState = fGeomPoolStateStack.push_back();
370515dcd36032997ce335daa0163c6d67e851bcad1commit-bot@chromium.org#ifdef SK_DEBUG
37125fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    newState.fPoolVertexBuffer = (GrVertexBuffer*)DEBUG_INVAL_BUFFER;
37225fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    newState.fPoolStartVertex = DEBUG_INVAL_START_IDX;
37325fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    newState.fPoolIndexBuffer = (GrIndexBuffer*)DEBUG_INVAL_BUFFER;
37425fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    newState.fPoolStartIndex = DEBUG_INVAL_START_IDX;
3750e51577a14f903ffeafa117a75954baeb173ffb9humper@google.com#else
3760e51577a14f903ffeafa117a75954baeb173ffb9humper@google.com    (void) newState; // silence compiler warning
37725fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com#endif
37825fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com}
37925fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com
38025fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.comvoid GrGpu::geometrySourceWillPop(const GeometrySrcState& restoredState) {
38125fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    // if popping last entry then pops are unbalanced with pushes
382f6de475e5cbd143f348ff7738919e397b7fe7f57tfarina@chromium.org    SkASSERT(fGeomPoolStateStack.count() > 1);
38325fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    fGeomPoolStateStack.pop_back();
38425fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com}
38525fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com
38674749cd45c29b4f5300e2518f2c2c765ce8ae208bsalomon@google.comvoid GrGpu::onDraw(const DrawInfo& info) {
387a7f84e150cb9e821267a8ca9e59c1ae9a3cfa300bsalomon@google.com    this->handleDirtyContext();
388eb6879f50a5564eeb981ec5616b55bf685eb76fcbsalomon@google.com    GrDrawState::AutoRestoreEffects are;
38926e18b593ab65e4d92dfbce92579d8bc180d4c2cbsalomon@google.com    if (!this->setupClipAndFlushState(PrimTypeToDrawType(info.primitiveType()),
3903ae0e6c2b213d45c370846a4d4182a6754ca493ecommit-bot@chromium.org                                      info.getDstCopy(), &are, info.getDevBounds())) {
391ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com        return;
392ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    }
39374749cd45c29b4f5300e2518f2c2c765ce8ae208bsalomon@google.com    this->onGpuDraw(info);
3941c13c9668a889e56a0c85b51b9f28139c25b76ffbsalomon@google.com}
3951c13c9668a889e56a0c85b51b9f28139c25b76ffbsalomon@google.com
39632184d81629e39809bb9e915286d8fe971a8ed68commit-bot@chromium.orgvoid GrGpu::onStencilPath(const GrPath* path, SkPath::FillType fill) {
39764aef2bacd1f5c25ffd9347aabd6265c9b60c0f4bsalomon@google.com    this->handleDirtyContext();
39864aef2bacd1f5c25ffd9347aabd6265c9b60c0f4bsalomon@google.com
399eb6879f50a5564eeb981ec5616b55bf685eb76fcbsalomon@google.com    GrDrawState::AutoRestoreEffects are;
4003ae0e6c2b213d45c370846a4d4182a6754ca493ecommit-bot@chromium.org    if (!this->setupClipAndFlushState(kStencilPath_DrawType, NULL, &are, NULL)) {
40164aef2bacd1f5c25ffd9347aabd6265c9b60c0f4bsalomon@google.com        return;
40264aef2bacd1f5c25ffd9347aabd6265c9b60c0f4bsalomon@google.com    }
40364aef2bacd1f5c25ffd9347aabd6265c9b60c0f4bsalomon@google.com
40464aef2bacd1f5c25ffd9347aabd6265c9b60c0f4bsalomon@google.com    this->onGpuStencilPath(path, fill);
40564aef2bacd1f5c25ffd9347aabd6265c9b60c0f4bsalomon@google.com}
40664aef2bacd1f5c25ffd9347aabd6265c9b60c0f4bsalomon@google.com
40732184d81629e39809bb9e915286d8fe971a8ed68commit-bot@chromium.org
40832184d81629e39809bb9e915286d8fe971a8ed68commit-bot@chromium.orgvoid GrGpu::onDrawPath(const GrPath* path, SkPath::FillType fill,
409c4dc0ad8e252a7e30d19b47d3d0d9f2c69faf854commit-bot@chromium.org                       const GrDeviceCoordTexture* dstCopy) {
410c4dc0ad8e252a7e30d19b47d3d0d9f2c69faf854commit-bot@chromium.org    this->handleDirtyContext();
411c4dc0ad8e252a7e30d19b47d3d0d9f2c69faf854commit-bot@chromium.org
412c4dc0ad8e252a7e30d19b47d3d0d9f2c69faf854commit-bot@chromium.org    drawState()->setDefaultVertexAttribs();
413c4dc0ad8e252a7e30d19b47d3d0d9f2c69faf854commit-bot@chromium.org
414c4dc0ad8e252a7e30d19b47d3d0d9f2c69faf854commit-bot@chromium.org    GrDrawState::AutoRestoreEffects are;
4153ae0e6c2b213d45c370846a4d4182a6754ca493ecommit-bot@chromium.org    if (!this->setupClipAndFlushState(kDrawPath_DrawType, dstCopy, &are, NULL)) {
416c4dc0ad8e252a7e30d19b47d3d0d9f2c69faf854commit-bot@chromium.org        return;
417c4dc0ad8e252a7e30d19b47d3d0d9f2c69faf854commit-bot@chromium.org    }
418c4dc0ad8e252a7e30d19b47d3d0d9f2c69faf854commit-bot@chromium.org
41932184d81629e39809bb9e915286d8fe971a8ed68commit-bot@chromium.org    this->onGpuDrawPath(path, fill);
420c4dc0ad8e252a7e30d19b47d3d0d9f2c69faf854commit-bot@chromium.org}
421c4dc0ad8e252a7e30d19b47d3d0d9f2c69faf854commit-bot@chromium.org
422ecc45365b6429ee4cbe1748dc6667b862d5f0f71commit-bot@chromium.orgvoid GrGpu::onDrawPaths(int pathCount, const GrPath** paths,
4239b62aa156bcf1db6f11af9302bf8bb8ef2567142commit-bot@chromium.org                        const SkMatrix* transforms, SkPath::FillType fill,
4249b62aa156bcf1db6f11af9302bf8bb8ef2567142commit-bot@chromium.org                        SkStrokeRec::Style style,
4259b62aa156bcf1db6f11af9302bf8bb8ef2567142commit-bot@chromium.org                        const GrDeviceCoordTexture* dstCopy) {
4269b62aa156bcf1db6f11af9302bf8bb8ef2567142commit-bot@chromium.org    this->handleDirtyContext();
4279b62aa156bcf1db6f11af9302bf8bb8ef2567142commit-bot@chromium.org
4289b62aa156bcf1db6f11af9302bf8bb8ef2567142commit-bot@chromium.org    drawState()->setDefaultVertexAttribs();
4299b62aa156bcf1db6f11af9302bf8bb8ef2567142commit-bot@chromium.org
4309b62aa156bcf1db6f11af9302bf8bb8ef2567142commit-bot@chromium.org    GrDrawState::AutoRestoreEffects are;
4319b62aa156bcf1db6f11af9302bf8bb8ef2567142commit-bot@chromium.org    if (!this->setupClipAndFlushState(kDrawPaths_DrawType, dstCopy, &are, NULL)) {
4329b62aa156bcf1db6f11af9302bf8bb8ef2567142commit-bot@chromium.org        return;
4339b62aa156bcf1db6f11af9302bf8bb8ef2567142commit-bot@chromium.org    }
4349b62aa156bcf1db6f11af9302bf8bb8ef2567142commit-bot@chromium.org
4359b62aa156bcf1db6f11af9302bf8bb8ef2567142commit-bot@chromium.org    this->onGpuDrawPaths(pathCount, paths, transforms, fill, style);
4369b62aa156bcf1db6f11af9302bf8bb8ef2567142commit-bot@chromium.org}
4379b62aa156bcf1db6f11af9302bf8bb8ef2567142commit-bot@chromium.org
4381c13c9668a889e56a0c85b51b9f28139c25b76ffbsalomon@google.comvoid GrGpu::finalizeReservedVertices() {
439f6de475e5cbd143f348ff7738919e397b7fe7f57tfarina@chromium.org    SkASSERT(NULL != fVertexPool);
4408341eb76fbc54593e873f5589961e02793e7f15fcommit-bot@chromium.org    fVertexPool->unmap();
4411c13c9668a889e56a0c85b51b9f28139c25b76ffbsalomon@google.com}
4421c13c9668a889e56a0c85b51b9f28139c25b76ffbsalomon@google.com
4431c13c9668a889e56a0c85b51b9f28139c25b76ffbsalomon@google.comvoid GrGpu::finalizeReservedIndices() {
444f6de475e5cbd143f348ff7738919e397b7fe7f57tfarina@chromium.org    SkASSERT(NULL != fIndexPool);
4458341eb76fbc54593e873f5589961e02793e7f15fcommit-bot@chromium.org    fIndexPool->unmap();
4461c13c9668a889e56a0c85b51b9f28139c25b76ffbsalomon@google.com}
4471c13c9668a889e56a0c85b51b9f28139c25b76ffbsalomon@google.com
4481c13c9668a889e56a0c85b51b9f28139c25b76ffbsalomon@google.comvoid GrGpu::prepareVertexPool() {
4491c13c9668a889e56a0c85b51b9f28139c25b76ffbsalomon@google.com    if (NULL == fVertexPool) {
450f6de475e5cbd143f348ff7738919e397b7fe7f57tfarina@chromium.org        SkASSERT(0 == fVertexPoolUseCnt);
451c377baf406996aed18d82d328029c82dbc3b8ddatomhudson@google.com        fVertexPool = SkNEW_ARGS(GrVertexBufferAllocPool, (this, true,
452d302f1401b3c9aea094804bad4e76de98782cfe8bsalomon@google.com                                                  VERTEX_POOL_VB_SIZE,
453c377baf406996aed18d82d328029c82dbc3b8ddatomhudson@google.com                                                  VERTEX_POOL_VB_COUNT));
45411f0b519766dabed4ce882f3ee7c07a68d3ccb52bsalomon@google.com        fVertexPool->releaseGpuRef();
45525fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    } else if (!fVertexPoolUseCnt) {
456d302f1401b3c9aea094804bad4e76de98782cfe8bsalomon@google.com        // the client doesn't have valid data in the pool
4571c13c9668a889e56a0c85b51b9f28139c25b76ffbsalomon@google.com        fVertexPool->reset();
4581c13c9668a889e56a0c85b51b9f28139c25b76ffbsalomon@google.com    }
4591c13c9668a889e56a0c85b51b9f28139c25b76ffbsalomon@google.com}
4601c13c9668a889e56a0c85b51b9f28139c25b76ffbsalomon@google.com
4611c13c9668a889e56a0c85b51b9f28139c25b76ffbsalomon@google.comvoid GrGpu::prepareIndexPool() {
4629d18b7873ce9b44f130a41e0cbd0a3df76ab9adfsenorblanco@chromium.org    if (NULL == fIndexPool) {
463f6de475e5cbd143f348ff7738919e397b7fe7f57tfarina@chromium.org        SkASSERT(0 == fIndexPoolUseCnt);
464c377baf406996aed18d82d328029c82dbc3b8ddatomhudson@google.com        fIndexPool = SkNEW_ARGS(GrIndexBufferAllocPool, (this, true,
46525fd36c7efc0287b6a2a82463eacaeaf91ca07b9bsalomon@google.com                                                INDEX_POOL_IB_SIZE,
466c377baf406996aed18d82d328029c82dbc3b8ddatomhudson@google.com                                                INDEX_POOL_IB_COUNT));
46711f0b519766dabed4ce882f3ee7c07a68d3ccb52bsalomon@google.com        fIndexPool->releaseGpuRef();
46825fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    } else if (!fIndexPoolUseCnt) {
469d302f1401b3c9aea094804bad4e76de98782cfe8bsalomon@google.com        // the client doesn't have valid data in the pool
4701c13c9668a889e56a0c85b51b9f28139c25b76ffbsalomon@google.com        fIndexPool->reset();
4711c13c9668a889e56a0c85b51b9f28139c25b76ffbsalomon@google.com    }
472ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com}
473ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
474a63389843dd18003382d61c2e4610af09ed07d38jvanverth@google.combool GrGpu::onReserveVertexSpace(size_t vertexSize,
47525fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com                                 int vertexCount,
47625fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com                                 void** vertices) {
47725fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    GeometryPoolState& geomPoolState = fGeomPoolStateStack.back();
478d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com
479f6de475e5cbd143f348ff7738919e397b7fe7f57tfarina@chromium.org    SkASSERT(vertexCount > 0);
480f6de475e5cbd143f348ff7738919e397b7fe7f57tfarina@chromium.org    SkASSERT(NULL != vertices);
481d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com
48225fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    this->prepareVertexPool();
483d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com
484a63389843dd18003382d61c2e4610af09ed07d38jvanverth@google.com    *vertices = fVertexPool->makeSpace(vertexSize,
48525fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com                                       vertexCount,
48625fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com                                       &geomPoolState.fPoolVertexBuffer,
48725fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com                                       &geomPoolState.fPoolStartVertex);
48825fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    if (NULL == *vertices) {
48925fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com        return false;
49025fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    }
49125fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    ++fVertexPoolUseCnt;
49225fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    return true;
49325fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com}
4941c13c9668a889e56a0c85b51b9f28139c25b76ffbsalomon@google.com
49525fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.combool GrGpu::onReserveIndexSpace(int indexCount, void** indices) {
49625fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    GeometryPoolState& geomPoolState = fGeomPoolStateStack.back();
497d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com
498f6de475e5cbd143f348ff7738919e397b7fe7f57tfarina@chromium.org    SkASSERT(indexCount > 0);
499f6de475e5cbd143f348ff7738919e397b7fe7f57tfarina@chromium.org    SkASSERT(NULL != indices);
5001c13c9668a889e56a0c85b51b9f28139c25b76ffbsalomon@google.com
50125fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    this->prepareIndexPool();
5021c13c9668a889e56a0c85b51b9f28139c25b76ffbsalomon@google.com
50325fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    *indices = fIndexPool->makeSpace(indexCount,
50425fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com                                     &geomPoolState.fPoolIndexBuffer,
50525fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com                                     &geomPoolState.fPoolStartIndex);
50625fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    if (NULL == *indices) {
50725fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com        return false;
508ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    }
50925fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    ++fIndexPoolUseCnt;
510ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com    return true;
511ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com}
512ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
51325fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.comvoid GrGpu::releaseReservedVertexSpace() {
51425fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    const GeometrySrcState& geoSrc = this->getGeomSrc();
515f6de475e5cbd143f348ff7738919e397b7fe7f57tfarina@chromium.org    SkASSERT(kReserved_GeometrySrcType == geoSrc.fVertexSrc);
516b75b0a0b8492e14c7728e0a0881f87dc64ce60f9jvanverth@google.com    size_t bytes = geoSrc.fVertexCount * geoSrc.fVertexSize;
51725fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    fVertexPool->putBack(bytes);
51825fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    --fVertexPoolUseCnt;
51925fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com}
52025fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com
52125fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.comvoid GrGpu::releaseReservedIndexSpace() {
52225fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    const GeometrySrcState& geoSrc = this->getGeomSrc();
523f6de475e5cbd143f348ff7738919e397b7fe7f57tfarina@chromium.org    SkASSERT(kReserved_GeometrySrcType == geoSrc.fIndexSrc);
52425fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    size_t bytes = geoSrc.fIndexCount * sizeof(uint16_t);
52525fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    fIndexPool->putBack(bytes);
52625fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    --fIndexPoolUseCnt;
52725fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com}
5281c13c9668a889e56a0c85b51b9f28139c25b76ffbsalomon@google.com
529bcdbbe61e1a3f89545b2c1461164f0f8bf5f0797bsalomon@google.comvoid GrGpu::onSetVertexSourceToArray(const void* vertexArray, int vertexCount) {
530bcdbbe61e1a3f89545b2c1461164f0f8bf5f0797bsalomon@google.com    this->prepareVertexPool();
53125fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    GeometryPoolState& geomPoolState = fGeomPoolStateStack.back();
532515dcd36032997ce335daa0163c6d67e851bcad1commit-bot@chromium.org#ifdef SK_DEBUG
5331c13c9668a889e56a0c85b51b9f28139c25b76ffbsalomon@google.com    bool success =
5341c13c9668a889e56a0c85b51b9f28139c25b76ffbsalomon@google.com#endif
535b75b0a0b8492e14c7728e0a0881f87dc64ce60f9jvanverth@google.com    fVertexPool->appendVertices(this->getVertexSize(),
5361c13c9668a889e56a0c85b51b9f28139c25b76ffbsalomon@google.com                                vertexCount,
5371c13c9668a889e56a0c85b51b9f28139c25b76ffbsalomon@google.com                                vertexArray,
53825fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com                                &geomPoolState.fPoolVertexBuffer,
53925fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com                                &geomPoolState.fPoolStartVertex);
54025fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    ++fVertexPoolUseCnt;
5411c13c9668a889e56a0c85b51b9f28139c25b76ffbsalomon@google.com    GR_DEBUGASSERT(success);
5421c13c9668a889e56a0c85b51b9f28139c25b76ffbsalomon@google.com}
5431c13c9668a889e56a0c85b51b9f28139c25b76ffbsalomon@google.com
544bcdbbe61e1a3f89545b2c1461164f0f8bf5f0797bsalomon@google.comvoid GrGpu::onSetIndexSourceToArray(const void* indexArray, int indexCount) {
545bcdbbe61e1a3f89545b2c1461164f0f8bf5f0797bsalomon@google.com    this->prepareIndexPool();
54625fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    GeometryPoolState& geomPoolState = fGeomPoolStateStack.back();
547515dcd36032997ce335daa0163c6d67e851bcad1commit-bot@chromium.org#ifdef SK_DEBUG
5481c13c9668a889e56a0c85b51b9f28139c25b76ffbsalomon@google.com    bool success =
5491c13c9668a889e56a0c85b51b9f28139c25b76ffbsalomon@google.com#endif
5501c13c9668a889e56a0c85b51b9f28139c25b76ffbsalomon@google.com    fIndexPool->appendIndices(indexCount,
5511c13c9668a889e56a0c85b51b9f28139c25b76ffbsalomon@google.com                              indexArray,
55225fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com                              &geomPoolState.fPoolIndexBuffer,
55325fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com                              &geomPoolState.fPoolStartIndex);
55425fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    ++fIndexPoolUseCnt;
5551c13c9668a889e56a0c85b51b9f28139c25b76ffbsalomon@google.com    GR_DEBUGASSERT(success);
556ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com}
557ac10a2d039c5d52eed66e27cbbc503ab523c1cd5reed@google.com
55825fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.comvoid GrGpu::releaseVertexArray() {
55925fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    // if vertex source was array, we stowed data in the pool
56025fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    const GeometrySrcState& geoSrc = this->getGeomSrc();
561f6de475e5cbd143f348ff7738919e397b7fe7f57tfarina@chromium.org    SkASSERT(kArray_GeometrySrcType == geoSrc.fVertexSrc);
562b75b0a0b8492e14c7728e0a0881f87dc64ce60f9jvanverth@google.com    size_t bytes = geoSrc.fVertexCount * geoSrc.fVertexSize;
56325fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    fVertexPool->putBack(bytes);
56425fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    --fVertexPoolUseCnt;
56525fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com}
56625fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com
56725fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.comvoid GrGpu::releaseIndexArray() {
56825fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    // if index source was array, we stowed data in the pool
56925fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    const GeometrySrcState& geoSrc = this->getGeomSrc();
570f6de475e5cbd143f348ff7738919e397b7fe7f57tfarina@chromium.org    SkASSERT(kArray_GeometrySrcType == geoSrc.fIndexSrc);
57125fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    size_t bytes = geoSrc.fIndexCount * sizeof(uint16_t);
57225fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    fIndexPool->putBack(bytes);
57325fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com    --fIndexPoolUseCnt;
57425fb21f5df904c6f111bbf8f07e6a6c339416d09bsalomon@google.com}
575