127847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com
2ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com/*
3ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * Copyright 2011 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.
727847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com */
827847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com
91fadb20c50c2302565f73ae12057a6f5d22192c7bsalomon@google.com#include "GrContext.h"
101fadb20c50c2302565f73ae12057a6f5d22192c7bsalomon@google.com
11bfe2b9d3a290d0153b82617cd6b65a4814fe89e3jvanverth@google.com#include "GrAARectRenderer.h"
121d89e8d1a46dfd8dd0a417edec5409721a1600a6joshualitt#include "GrAtlasTextContext.h"
130823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt#include "GrBatch.h"
147c3a2f834e0ba3f11a3129d5348b393efcc9b0e1joshualitt#include "GrBatchFontCache.h"
150823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt#include "GrBatchTarget.h"
16e590266294c4c92e4e4c2f06f267ac5751d07562joshualitt#include "GrBatchTest.h"
175478d427c6e67c986a3390162c8fec77c466058ajoshualitt#include "GrDefaultGeoProcFactory.h"
18453cf40ac7702722695bb09ae2c6df44c19d008bbsalomon#include "GrGpuResource.h"
193582d3ee9fffdec715f5e4949a241ab08e6271ecbsalomon#include "GrGpuResourcePriv.h"
204784182993a336b673619f3eb13ce2539aa890dacommit-bot@chromium.org#include "GrDrawTargetCaps.h"
215478d427c6e67c986a3390162c8fec77c466058ajoshualitt#include "GrGpu.h"
22dcb8ef9e866b2674e8f9a70b761fcc4fec87dbbecommit-bot@chromium.org#include "GrIndexBuffer.h"
234784182993a336b673619f3eb13ce2539aa890dacommit-bot@chromium.org#include "GrInOrderDrawBuffer.h"
24e930a075625d3d90c023c2570a6a4cae1a4b484frobertphillips@google.com#include "GrLayerCache.h"
2581312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org#include "GrOvalRenderer.h"
2627847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com#include "GrPathRenderer.h"
27d22b6e4351e552a8379d7781096d9e79feeae263tomhudson@google.com#include "GrPathUtils.h"
286bc1b5fab8554a9cb643277b4867965dd4535cd6bsalomon#include "GrRenderTargetPriv.h"
290ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon#include "GrResourceCache.h"
30d309e7aa0efa2d5dd7e7b1af97026fcd3a047e98bsalomon#include "GrResourceProvider.h"
3172176b2d38db005863a54e3dd6657bbabd068bb6robertphillips@google.com#include "GrSoftwarePathRenderer.h"
32c6cb56f36c4aad8ed45486a3bb4de614bb822f1bkkinnunen#include "GrStencilAndCoverTextContext.h"
33d58a0ba9cff9fcefe5047e88ccb4a6e76c591c40egdaniel#include "GrStrokeInfo.h"
34afbf2d6273cd22c683f20a7e5773843876af3085bsalomon#include "GrSurfacePriv.h"
35b7133bed55af8dd4ca9427892bb1a5623dbaccf0joshualitt#include "GrTextBlobCache.h"
36afbf2d6273cd22c683f20a7e5773843876af3085bsalomon#include "GrTexturePriv.h"
37bbcb38df4f7477aa0a38da00a0757586a0125954egdaniel#include "GrTraceMarker.h"
382a05de0c049a8648942a55016126a1f92e1c14d6commit-bot@chromium.org#include "GrTracing.h"
39cb8979d088a66ebaf41f10ba6f5c830615aa0e03bsalomon#include "GrVertices.h"
40d58a0ba9cff9fcefe5047e88ccb4a6e76c591c40egdaniel#include "SkDashPathPriv.h"
4181beccc4fb1396fe94af15bfce26e68b82b93809bsalomon#include "SkConfig8888.h"
427111d463cee893a479280c7af41757e709e33ef5reed@google.com#include "SkGr.h"
434784182993a336b673619f3eb13ce2539aa890dacommit-bot@chromium.org#include "SkRRect.h"
445f74cf8c49701f514b69dc6f1a8b5c0ffd78af0asugoi@google.com#include "SkStrokeRec.h"
45dcb8ef9e866b2674e8f9a70b761fcc4fec87dbbecommit-bot@chromium.org#include "SkTLazy.h"
464784182993a336b673619f3eb13ce2539aa890dacommit-bot@chromium.org#include "SkTLS.h"
47933e65d914eb86b1fbbf8ea9cf1da58ac7c42500commit-bot@chromium.org#include "SkTraceEvent.h"
4827847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com
495478d427c6e67c986a3390162c8fec77c466058ajoshualitt#include "effects/GrConfigConversionEffect.h"
505478d427c6e67c986a3390162c8fec77c466058ajoshualitt#include "effects/GrDashingEffect.h"
515478d427c6e67c986a3390162c8fec77c466058ajoshualitt#include "effects/GrSingleTextureEffect.h"
525478d427c6e67c986a3390162c8fec77c466058ajoshualitt
53f6de475e5cbd143f348ff7738919e397b7fe7f57tfarina@chromium.org#define ASSERT_OWNED_RESOURCE(R) SkASSERT(!(R) || (R)->getContext() == this)
545f5a8d7599b8e248633ac122294b7a01401fedcbjoshualitt#define RETURN_IF_ABANDONED if (!fDrawBuffer) { return; }
555f5a8d7599b8e248633ac122294b7a01401fedcbjoshualitt#define RETURN_FALSE_IF_ABANDONED if (!fDrawBuffer) { return false; }
565f5a8d7599b8e248633ac122294b7a01401fedcbjoshualitt#define RETURN_NULL_IF_ABANDONED if (!fDrawBuffer) { return NULL; }
57bc4b654af85fa67bdd9cc1b88747b8c394a00e27bsalomon@google.com
58f21dab95405979a4aff9f6a741c818304a67f220bsalomonclass GrContext::AutoCheckFlush {
59f21dab95405979a4aff9f6a741c818304a67f220bsalomonpublic:
60f21dab95405979a4aff9f6a741c818304a67f220bsalomon    AutoCheckFlush(GrContext* context) : fContext(context) { SkASSERT(context); }
61f21dab95405979a4aff9f6a741c818304a67f220bsalomon
62f21dab95405979a4aff9f6a741c818304a67f220bsalomon    ~AutoCheckFlush() {
63f21dab95405979a4aff9f6a741c818304a67f220bsalomon        if (fContext->fFlushToReduceCacheSize) {
64f21dab95405979a4aff9f6a741c818304a67f220bsalomon            fContext->flush();
65f21dab95405979a4aff9f6a741c818304a67f220bsalomon        }
66f21dab95405979a4aff9f6a741c818304a67f220bsalomon    }
67f21dab95405979a4aff9f6a741c818304a67f220bsalomon
68f21dab95405979a4aff9f6a741c818304a67f220bsalomonprivate:
69f21dab95405979a4aff9f6a741c818304a67f220bsalomon    GrContext* fContext;
70f21dab95405979a4aff9f6a741c818304a67f220bsalomon};
71f21dab95405979a4aff9f6a741c818304a67f220bsalomon
729c6d4d744a9e0375d0e7d7a7b19558f5259fc3c3krajcevskiGrContext* GrContext::Create(GrBackend backend, GrBackendContext backendContext,
739c6d4d744a9e0375d0e7d7a7b19558f5259fc3c3krajcevski                             const Options* opts) {
749c6d4d744a9e0375d0e7d7a7b19558f5259fc3c3krajcevski    GrContext* context;
759c6d4d744a9e0375d0e7d7a7b19558f5259fc3c3krajcevski    if (NULL == opts) {
769c6d4d744a9e0375d0e7d7a7b19558f5259fc3c3krajcevski        context = SkNEW_ARGS(GrContext, (Options()));
779c6d4d744a9e0375d0e7d7a7b19558f5259fc3c3krajcevski    } else {
789c6d4d744a9e0375d0e7d7a7b19558f5259fc3c3krajcevski        context = SkNEW_ARGS(GrContext, (*opts));
799c6d4d744a9e0375d0e7d7a7b19558f5259fc3c3krajcevski    }
809c6d4d744a9e0375d0e7d7a7b19558f5259fc3c3krajcevski
816e4e65066a7c0dbc9bfbfe4b8f5d49c3d8a79b59bsalomon@google.com    if (context->init(backend, backendContext)) {
826e4e65066a7c0dbc9bfbfe4b8f5d49c3d8a79b59bsalomon@google.com        return context;
836e4e65066a7c0dbc9bfbfe4b8f5d49c3d8a79b59bsalomon@google.com    } else {
846e4e65066a7c0dbc9bfbfe4b8f5d49c3d8a79b59bsalomon@google.com        context->unref();
856e4e65066a7c0dbc9bfbfe4b8f5d49c3d8a79b59bsalomon@google.com        return NULL;
8627847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com    }
8727847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com}
8827847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com
890acd0d33fd69b6603fa22f88fa45c96aa0907d4djoshualittstatic int32_t gNextID = 1;
900acd0d33fd69b6603fa22f88fa45c96aa0907d4djoshualittstatic int32_t next_id() {
910acd0d33fd69b6603fa22f88fa45c96aa0907d4djoshualitt    int32_t id;
920acd0d33fd69b6603fa22f88fa45c96aa0907d4djoshualitt    do {
930acd0d33fd69b6603fa22f88fa45c96aa0907d4djoshualitt        id = sk_atomic_inc(&gNextID);
940acd0d33fd69b6603fa22f88fa45c96aa0907d4djoshualitt    } while (id == SK_InvalidGenID);
950acd0d33fd69b6603fa22f88fa45c96aa0907d4djoshualitt    return id;
960acd0d33fd69b6603fa22f88fa45c96aa0907d4djoshualitt}
970acd0d33fd69b6603fa22f88fa45c96aa0907d4djoshualitt
980acd0d33fd69b6603fa22f88fa45c96aa0907d4djoshualittGrContext::GrContext(const Options& opts) : fOptions(opts), fUniqueID(next_id()) {
996e4e65066a7c0dbc9bfbfe4b8f5d49c3d8a79b59bsalomon@google.com    fGpu = NULL;
100d309e7aa0efa2d5dd7e7b1af97026fcd3a047e98bsalomon    fResourceCache = NULL;
101d309e7aa0efa2d5dd7e7b1af97026fcd3a047e98bsalomon    fResourceProvider = NULL;
1026e4e65066a7c0dbc9bfbfe4b8f5d49c3d8a79b59bsalomon@google.com    fPathRendererChain = NULL;
1036e4e65066a7c0dbc9bfbfe4b8f5d49c3d8a79b59bsalomon@google.com    fSoftwarePathRenderer = NULL;
1047c3a2f834e0ba3f11a3129d5348b393efcc9b0e1joshualitt    fBatchFontCache = NULL;
1056e4e65066a7c0dbc9bfbfe4b8f5d49c3d8a79b59bsalomon@google.com    fDrawBuffer = NULL;
106f21dab95405979a4aff9f6a741c818304a67f220bsalomon    fFlushToReduceCacheSize = false;
1076e4e65066a7c0dbc9bfbfe4b8f5d49c3d8a79b59bsalomon@google.com    fAARectRenderer = NULL;
10881312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org    fOvalRenderer = NULL;
10944a91dcf2542c2aa93f159ebbb5bf813ae7362c0robertphillips@google.com    fMaxTextureSizeOverride = 1 << 20;
1106e4e65066a7c0dbc9bfbfe4b8f5d49c3d8a79b59bsalomon@google.com}
1116e4e65066a7c0dbc9bfbfe4b8f5d49c3d8a79b59bsalomon@google.com
1126e4e65066a7c0dbc9bfbfe4b8f5d49c3d8a79b59bsalomon@google.combool GrContext::init(GrBackend backend, GrBackendContext backendContext) {
113f6de475e5cbd143f348ff7738919e397b7fe7f57tfarina@chromium.org    SkASSERT(NULL == fGpu);
1146e4e65066a7c0dbc9bfbfe4b8f5d49c3d8a79b59bsalomon@google.com
1156e4e65066a7c0dbc9bfbfe4b8f5d49c3d8a79b59bsalomon@google.com    fGpu = GrGpu::Create(backend, backendContext, this);
1166e4e65066a7c0dbc9bfbfe4b8f5d49c3d8a79b59bsalomon@google.com    if (NULL == fGpu) {
1176e4e65066a7c0dbc9bfbfe4b8f5d49c3d8a79b59bsalomon@google.com        return false;
1186e4e65066a7c0dbc9bfbfe4b8f5d49c3d8a79b59bsalomon@google.com    }
119334355742137cc238887d4f85856e6c4d9ec8aa8bsalomon    this->initCommon();
120334355742137cc238887d4f85856e6c4d9ec8aa8bsalomon    return true;
121334355742137cc238887d4f85856e6c4d9ec8aa8bsalomon}
1226e4e65066a7c0dbc9bfbfe4b8f5d49c3d8a79b59bsalomon@google.com
123334355742137cc238887d4f85856e6c4d9ec8aa8bsalomonvoid GrContext::initCommon() {
1240ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon    fResourceCache = SkNEW(GrResourceCache);
1250ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon    fResourceCache->setOverBudgetCallback(OverBudgetCB, this);
126d309e7aa0efa2d5dd7e7b1af97026fcd3a047e98bsalomon    fResourceProvider = SkNEW_ARGS(GrResourceProvider, (fGpu, fResourceCache));
1271836d337a85b82689287231091823f404d8cab43commit-bot@chromium.org
1284ec84da746d66e1bcb76ab2f8b94602b8e966589robertphillips    fLayerCache.reset(SkNEW_ARGS(GrLayerCache, (this)));
129e930a075625d3d90c023c2570a6a4cae1a4b484frobertphillips@google.com
130ed0bcad9c8147fd37c23bdda00ec27ec9ef8d66bbsalomon    fAARectRenderer = SkNEW(GrAARectRenderer);
131ed0bcad9c8147fd37c23bdda00ec27ec9ef8d66bbsalomon    fOvalRenderer = SkNEW(GrOvalRenderer);
1326e4e65066a7c0dbc9bfbfe4b8f5d49c3d8a79b59bsalomon@google.com
1336e4e65066a7c0dbc9bfbfe4b8f5d49c3d8a79b59bsalomon@google.com    fDidTestPMConversions = false;
1346e4e65066a7c0dbc9bfbfe4b8f5d49c3d8a79b59bsalomon@google.com
135e40d39725908d99d255496025411e5c9ca32663erobertphillips    fDrawBuffer = SkNEW_ARGS(GrInOrderDrawBuffer, (this));
1367c3a2f834e0ba3f11a3129d5348b393efcc9b0e1joshualitt
1377c3a2f834e0ba3f11a3129d5348b393efcc9b0e1joshualitt    // GrBatchFontCache will eventually replace GrFontCache
13862db8ba68b980245e0927b792747864ebd6fcb6ajoshualitt    fBatchFontCache = SkNEW_ARGS(GrBatchFontCache, (this));
139b7133bed55af8dd4ca9427892bb1a5623dbaccf0joshualitt
1400db6dfaeb2d1376ad393516fb22af7ecf62718fajoshualitt    fTextBlobCache.reset(SkNEW_ARGS(GrTextBlobCache, (TextBlobCacheOverBudgetCB, this)));
141c0af3173314e227611d8c5541ef2deee0052d412bsalomon@google.com}
142c0af3173314e227611d8c5541ef2deee0052d412bsalomon@google.com
14327847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.comGrContext::~GrContext() {
144733c062c09bfe3ec4a32658510136fc5850a6e2cbsalomon@google.com    if (NULL == fGpu) {
145733c062c09bfe3ec4a32658510136fc5850a6e2cbsalomon@google.com        return;
146733c062c09bfe3ec4a32658510136fc5850a6e2cbsalomon@google.com    }
147733c062c09bfe3ec4a32658510136fc5850a6e2cbsalomon@google.com
1488fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.com    this->flush();
1495acc0e36d987dff3172fd45a14b66c52a51d49e4robertphillips@google.com
150950b1b079a782e208c2f38cf222184fa1ca1006drobertphillips@google.com    for (int i = 0; i < fCleanUpData.count(); ++i) {
151950b1b079a782e208c2f38cf222184fa1ca1006drobertphillips@google.com        (*fCleanUpData[i].fFunc)(this, fCleanUpData[i].fInfo);
152950b1b079a782e208c2f38cf222184fa1ca1006drobertphillips@google.com    }
153950b1b079a782e208c2f38cf222184fa1ca1006drobertphillips@google.com
154d309e7aa0efa2d5dd7e7b1af97026fcd3a047e98bsalomon    SkDELETE(fResourceProvider);
1550ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon    SkDELETE(fResourceCache);
1567c3a2f834e0ba3f11a3129d5348b393efcc9b0e1joshualitt    SkDELETE(fBatchFontCache);
157334355742137cc238887d4f85856e6c4d9ec8aa8bsalomon    SkDELETE(fDrawBuffer);
1583008519e9f977cd60194841d558a4f45c28e9833bsalomon@google.com
159f6747b0b90b3a270ec7b7bdfdc211cf5c19f28c2robertphillips@google.com    fAARectRenderer->unref();
16081312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org    fOvalRenderer->unref();
161f6747b0b90b3a270ec7b7bdfdc211cf5c19f28c2robertphillips@google.com
162205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com    fGpu->unref();
163a4de8c257ea0be8ff7081f645249b6afe5c48e7ecommit-bot@chromium.org    SkSafeUnref(fPathRendererChain);
164a4de8c257ea0be8ff7081f645249b6afe5c48e7ecommit-bot@chromium.org    SkSafeUnref(fSoftwarePathRenderer);
16527847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com}
16627847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com
1672354f8432a7205571f04f9638a0018fb0b1fb282bsalomonvoid GrContext::abandonContext() {
168d309e7aa0efa2d5dd7e7b1af97026fcd3a047e98bsalomon    fResourceProvider->abandon();
169205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com    // abandon first to so destructors
170205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com    // don't try to free the resources in the API.
1710ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon    fResourceCache->abandonAll();
172c8dc1f74b6cdda9a43a638292a608c59c1d72d80bsalomon
173e3371304b8c06a29aa3581c8decd9046c712c5f6robertphillips    fGpu->contextAbandoned();
174205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com
1753008519e9f977cd60194841d558a4f45c28e9833bsalomon@google.com    // a path renderer may be holding onto resources that
1763008519e9f977cd60194841d558a4f45c28e9833bsalomon@google.com    // are now unusable
177a4de8c257ea0be8ff7081f645249b6afe5c48e7ecommit-bot@chromium.org    SkSafeSetNull(fPathRendererChain);
178a4de8c257ea0be8ff7081f645249b6afe5c48e7ecommit-bot@chromium.org    SkSafeSetNull(fSoftwarePathRenderer);
1793008519e9f977cd60194841d558a4f45c28e9833bsalomon@google.com
180e40d39725908d99d255496025411e5c9ca32663erobertphillips    SkDELETE(fDrawBuffer);
1818fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.com    fDrawBuffer = NULL;
182205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com
1837c3a2f834e0ba3f11a3129d5348b393efcc9b0e1joshualitt    fBatchFontCache->freeAll();
184e930a075625d3d90c023c2570a6a4cae1a4b484frobertphillips@google.com    fLayerCache->freeAll();
18526ffc00bfa09fe85c22ddcbeb0fc54c0eacb7859joshualitt    fTextBlobCache->freeAll();
1868fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.com}
1878fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.com
1880a208a117b2d7f2c2231aa357f1db4864dbdcba3bsalomon@google.comvoid GrContext::resetContext(uint32_t state) {
1890a208a117b2d7f2c2231aa357f1db4864dbdcba3bsalomon@google.com    fGpu->markContextDirty(state);
1908fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.com}
1918fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.com
1928fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.comvoid GrContext::freeGpuResources() {
1938fe72477f204b1a45393e6a64caa84fd287b805bbsalomon@google.com    this->flush();
194fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com
19549f085dddff10473b6ebf832a974288300224e60bsalomon    if (fDrawBuffer) {
196c8dc1f74b6cdda9a43a638292a608c59c1d72d80bsalomon        fDrawBuffer->purgeResources();
197c8dc1f74b6cdda9a43a638292a608c59c1d72d80bsalomon    }
198ff17584e1c15f68ccc296be517e8a6776a9ddabdrobertphillips@google.com
1997c3a2f834e0ba3f11a3129d5348b393efcc9b0e1joshualitt    fBatchFontCache->freeAll();
200e930a075625d3d90c023c2570a6a4cae1a4b484frobertphillips@google.com    fLayerCache->freeAll();
2013008519e9f977cd60194841d558a4f45c28e9833bsalomon@google.com    // a path renderer may be holding onto resources
202a4de8c257ea0be8ff7081f645249b6afe5c48e7ecommit-bot@chromium.org    SkSafeSetNull(fPathRendererChain);
203a4de8c257ea0be8ff7081f645249b6afe5c48e7ecommit-bot@chromium.org    SkSafeSetNull(fSoftwarePathRenderer);
2043033b9faac476fc22e264950764d3551a32e4db7bsalomon
2053033b9faac476fc22e264950764d3551a32e4db7bsalomon    fResourceCache->purgeAllUnlocked();
20627847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com}
20727847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com
20895c2003740c4cd01fd1b02ed93b9de7227b1d0f5commit-bot@chromium.orgvoid GrContext::getResourceCacheUsage(int* resourceCount, size_t* resourceBytes) const {
20971cb0c241e439b6ed746b90294d0b6916644a644bsalomon    if (resourceCount) {
2100ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon        *resourceCount = fResourceCache->getBudgetedResourceCount();
21171cb0c241e439b6ed746b90294d0b6916644a644bsalomon    }
21271cb0c241e439b6ed746b90294d0b6916644a644bsalomon    if (resourceBytes) {
2130ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon        *resourceBytes = fResourceCache->getBudgetedResourceBytes();
21471cb0c241e439b6ed746b90294d0b6916644a644bsalomon    }
215d8a57af725e8fa8905207df3cf7465be50598752commit-bot@chromium.org}
216d8a57af725e8fa8905207df3cf7465be50598752commit-bot@chromium.org
217c6cb56f36c4aad8ed45486a3bb4de614bb822f1bkkinnunenGrTextContext* GrContext::createTextContext(GrRenderTarget* renderTarget,
2186e8cd9671958c69babde9338c5c18a4c3d895575joshualitt                                            SkGpuDevice* gpuDevice,
219c6cb56f36c4aad8ed45486a3bb4de614bb822f1bkkinnunen                                            const SkDeviceProperties&
220c6cb56f36c4aad8ed45486a3bb4de614bb822f1bkkinnunen                                            leakyProperties,
221c6cb56f36c4aad8ed45486a3bb4de614bb822f1bkkinnunen                                            bool enableDistanceFieldFonts) {
222e9c0fc616d2a1632c285885b9b656b68ca8d4f24jvanverth    if (fGpu->caps()->shaderCaps()->pathRenderingSupport() && renderTarget->isMultisampled()) {
2238dc7c3a839b38b73af34cc2674a06f49eb1ce527egdaniel        GrStencilAttachment* sb = renderTarget->renderTargetPriv().attachStencilAttachment();
2246bc1b5fab8554a9cb643277b4867965dd4535cd6bsalomon        if (sb) {
2256e8cd9671958c69babde9338c5c18a4c3d895575joshualitt            return GrStencilAndCoverTextContext::Create(this, gpuDevice, leakyProperties);
2266bc1b5fab8554a9cb643277b4867965dd4535cd6bsalomon        }
2278c27a188a0b216021d439eb627622d17b9f78343jvanverth    }
2288c27a188a0b216021d439eb627622d17b9f78343jvanverth
2299bd2daff8e53a6f02c7e5d1e6aa330f89b8542a3joshualitt    return GrAtlasTextContext::Create(this, gpuDevice, leakyProperties, enableDistanceFieldFonts);
230c6cb56f36c4aad8ed45486a3bb4de614bb822f1bkkinnunen}
231c6cb56f36c4aad8ed45486a3bb4de614bb822f1bkkinnunen
232fea37b5e532dfe776269253afb9951e763c3b205bsalomon@google.com////////////////////////////////////////////////////////////////////////////////
233fea37b5e532dfe776269253afb9951e763c3b205bsalomon@google.com
234d2a6f4e419393d3c8d8fe332f11c4c6f88382e1dbsalomonbool GrContext::isConfigTexturable(GrPixelConfig config) const {
235d2a6f4e419393d3c8d8fe332f11c4c6f88382e1dbsalomon    return fGpu->caps()->isConfigTexturable(config);
236d2a6f4e419393d3c8d8fe332f11c4c6f88382e1dbsalomon}
237d2a6f4e419393d3c8d8fe332f11c4c6f88382e1dbsalomon
238d2a6f4e419393d3c8d8fe332f11c4c6f88382e1dbsalomonbool GrContext::npotTextureTileSupport() const {
239d2a6f4e419393d3c8d8fe332f11c4c6f88382e1dbsalomon    return fGpu->caps()->npotTextureTileSupport();
240d2a6f4e419393d3c8d8fe332f11c4c6f88382e1dbsalomon}
241d2a6f4e419393d3c8d8fe332f11c4c6f88382e1dbsalomon
24271cb0c241e439b6ed746b90294d0b6916644a644bsalomonvoid GrContext::OverBudgetCB(void* data) {
24349f085dddff10473b6ebf832a974288300224e60bsalomon    SkASSERT(data);
244f21dab95405979a4aff9f6a741c818304a67f220bsalomon
245cae27fed5e45e8899e56ece22b27e8958ffc0162commit-bot@chromium.org    GrContext* context = reinterpret_cast<GrContext*>(data);
246f21dab95405979a4aff9f6a741c818304a67f220bsalomon
247f21dab95405979a4aff9f6a741c818304a67f220bsalomon    // Flush the InOrderDrawBuffer to possibly free up some textures
248f21dab95405979a4aff9f6a741c818304a67f220bsalomon    context->fFlushToReduceCacheSize = true;
249cae27fed5e45e8899e56ece22b27e8958ffc0162commit-bot@chromium.org}
250cae27fed5e45e8899e56ece22b27e8958ffc0162commit-bot@chromium.org
2510db6dfaeb2d1376ad393516fb22af7ecf62718fajoshualittvoid GrContext::TextBlobCacheOverBudgetCB(void* data) {
2520db6dfaeb2d1376ad393516fb22af7ecf62718fajoshualitt    SkASSERT(data);
2530db6dfaeb2d1376ad393516fb22af7ecf62718fajoshualitt
2540db6dfaeb2d1376ad393516fb22af7ecf62718fajoshualitt    // Unlike the GrResourceCache, TextBlobs are drawn at the SkGpuDevice level, therefore they
2550db6dfaeb2d1376ad393516fb22af7ecf62718fajoshualitt    // cannot use fFlushTorReduceCacheSize because it uses AutoCheckFlush.  The solution is to move
2560db6dfaeb2d1376ad393516fb22af7ecf62718fajoshualitt    // drawText calls to below the GrContext level, but this is not trivial because they call
2570db6dfaeb2d1376ad393516fb22af7ecf62718fajoshualitt    // drawPath on SkGpuDevice
2580db6dfaeb2d1376ad393516fb22af7ecf62718fajoshualitt    GrContext* context = reinterpret_cast<GrContext*>(data);
2590db6dfaeb2d1376ad393516fb22af7ecf62718fajoshualitt    context->flush();
2600db6dfaeb2d1376ad393516fb22af7ecf62718fajoshualitt}
2610db6dfaeb2d1376ad393516fb22af7ecf62718fajoshualitt
262919583674bd5daeb60327c0bc1ce8aaa80d54e13bsalomon@google.comint GrContext::getMaxTextureSize() const {
263972f9cd7a063d0544f8c919fd12b9a3adbd12b24commit-bot@chromium.org    return SkTMin(fGpu->caps()->maxTextureSize(), fMaxTextureSizeOverride);
264919583674bd5daeb60327c0bc1ce8aaa80d54e13bsalomon@google.com}
265919583674bd5daeb60327c0bc1ce8aaa80d54e13bsalomon@google.com
266919583674bd5daeb60327c0bc1ce8aaa80d54e13bsalomon@google.comint GrContext::getMaxRenderTargetSize() const {
267bcce8926524827775539874346dd424a9510dbc9bsalomon@google.com    return fGpu->caps()->maxRenderTargetSize();
26827847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com}
26927847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com
2708a70eef71cf369803e97ffea786f43f944de758ebsalomon@google.comint GrContext::getMaxSampleCount() const {
271bcce8926524827775539874346dd424a9510dbc9bsalomon@google.com    return fGpu->caps()->maxSampleCount();
2728a70eef71cf369803e97ffea786f43f944de758ebsalomon@google.com}
2738a70eef71cf369803e97ffea786f43f944de758ebsalomon@google.com
27427847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com///////////////////////////////////////////////////////////////////////////////
27527847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com
276fd03d4a829efe2d77a712fd991927c55f59a2ffecommit-bot@chromium.orgvoid GrContext::clear(const SkIRect* rect,
27707ea2db0260d8e6cd2bf605571b68b1c574b5a77bsalomon@google.com                      const GrColor color,
27856ce48ade325f6f49acb0da31d6252806e4ed7efrobertphillips@google.com                      bool canIgnoreRect,
27941ebbddd76b747d5fb32c02dda0de3d03a3edda5bsalomon                      GrRenderTarget* renderTarget) {
2805f5a8d7599b8e248633ac122294b7a01401fedcbjoshualitt    RETURN_IF_ABANDONED
28141ebbddd76b747d5fb32c02dda0de3d03a3edda5bsalomon    ASSERT_OWNED_RESOURCE(renderTarget);
28289c62980c1eb50b2090f33312086c7e8c66739b4bsalomon    SkASSERT(renderTarget);
28389c62980c1eb50b2090f33312086c7e8c66739b4bsalomon
284f21dab95405979a4aff9f6a741c818304a67f220bsalomon    AutoCheckFlush acf(this);
285d78a168ec2ec2c07c0c1845e6a1781988e4a52d9egdaniel    GR_CREATE_TRACE_MARKER_CONTEXT("GrContext::clear", this);
286570d2f81a65fc868d6300a7edf34c0d5d048c5d6joshualitt    GrDrawTarget* target = this->prepareToDraw();
28741ebbddd76b747d5fb32c02dda0de3d03a3edda5bsalomon    if (NULL == target) {
28841ebbddd76b747d5fb32c02dda0de3d03a3edda5bsalomon        return;
28941ebbddd76b747d5fb32c02dda0de3d03a3edda5bsalomon    }
29041ebbddd76b747d5fb32c02dda0de3d03a3edda5bsalomon    target->clear(rect, color, canIgnoreRect, renderTarget);
29127847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com}
29227847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com
29325d9c154087d2132a51d1ca74a104726f60ef380joshualittvoid GrContext::drawPaint(GrRenderTarget* rt,
294570d2f81a65fc868d6300a7edf34c0d5d048c5d6joshualitt                          const GrClip& clip,
29525d9c154087d2132a51d1ca74a104726f60ef380joshualitt                          const GrPaint& origPaint,
29625d9c154087d2132a51d1ca74a104726f60ef380joshualitt                          const SkMatrix& viewMatrix) {
2975f5a8d7599b8e248633ac122294b7a01401fedcbjoshualitt    RETURN_IF_ABANDONED
29827847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com    // set rect to be big enough to fill the space, but not super-huge, so we
29927847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com    // don't overflow fixed-point implementations
300fd03d4a829efe2d77a712fd991927c55f59a2ffecommit-bot@chromium.org    SkRect r;
301d302f1401b3c9aea094804bad4e76de98782cfe8bsalomon@google.com    r.setLTRB(0, 0,
30225d9c154087d2132a51d1ca74a104726f60ef380joshualitt              SkIntToScalar(rt->width()),
30325d9c154087d2132a51d1ca74a104726f60ef380joshualitt              SkIntToScalar(rt->height()));
3045dc26b97366934ba0f896cea02a3fec027d5d5c1bsalomon@google.com    SkTCopyOnFirstWrite<GrPaint> paint(origPaint);
3058fc6c2d82c1f30ff82274334c01f0799def6a609joshualitt
3068fc6c2d82c1f30ff82274334c01f0799def6a609joshualitt    // by definition this fills the entire clip, no need for AA
3078fc6c2d82c1f30ff82274334c01f0799def6a609joshualitt    if (paint->isAntiAlias()) {
3088fc6c2d82c1f30ff82274334c01f0799def6a609joshualitt        paint.writable()->setAntiAlias(false);
3098fc6c2d82c1f30ff82274334c01f0799def6a609joshualitt    }
3108fc6c2d82c1f30ff82274334c01f0799def6a609joshualitt
3118fc6c2d82c1f30ff82274334c01f0799def6a609joshualitt    bool isPerspective = viewMatrix.hasPerspective();
3128f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
3134f83be8f865921b60e3326b3fed6d5bc8281b541bsalomon@google.com    // We attempt to map r by the inverse matrix and draw that. mapRect will
3144f83be8f865921b60e3326b3fed6d5bc8281b541bsalomon@google.com    // map the four corners and bound them with a new rect. This will not
3154f83be8f865921b60e3326b3fed6d5bc8281b541bsalomon@google.com    // produce a correct result for some perspective matrices.
3168fc6c2d82c1f30ff82274334c01f0799def6a609joshualitt    if (!isPerspective) {
3175531d51ce7426bdae7563547326fcf0bf926a083joshualitt        SkMatrix inverse;
3185531d51ce7426bdae7563547326fcf0bf926a083joshualitt        if (!viewMatrix.invert(&inverse)) {
31938406c82b913350e55fa04af8c1941cd9b4aff52tfarina            SkDebugf("Could not invert matrix\n");
3208c2fe99ed2c210317786683e8c1f1e86cff0be49bsalomon@google.com            return;
3218c2fe99ed2c210317786683e8c1f1e86cff0be49bsalomon@google.com        }
32227847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com        inverse.mapRect(&r);
323570d2f81a65fc868d6300a7edf34c0d5d048c5d6joshualitt        this->drawRect(rt, clip, *paint, viewMatrix, r);
32427847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com    } else {
3258fc6c2d82c1f30ff82274334c01f0799def6a609joshualitt        SkMatrix localMatrix;
3268fc6c2d82c1f30ff82274334c01f0799def6a609joshualitt        if (!viewMatrix.invert(&localMatrix)) {
32738406c82b913350e55fa04af8c1941cd9b4aff52tfarina            SkDebugf("Could not invert matrix\n");
3283cbaa2d4da8bc39a99bf3afaaab43cc6dc481723bsalomon@google.com            return;
3298c2fe99ed2c210317786683e8c1f1e86cff0be49bsalomon@google.com        }
3308fc6c2d82c1f30ff82274334c01f0799def6a609joshualitt
3318fc6c2d82c1f30ff82274334c01f0799def6a609joshualitt        AutoCheckFlush acf(this);
3328dd688b7569df569a672a8a67b2db86a9d376cfcegdaniel        GrPipelineBuilder pipelineBuilder;
333570d2f81a65fc868d6300a7edf34c0d5d048c5d6joshualitt        GrDrawTarget* target = this->prepareToDraw(&pipelineBuilder, rt, clip, paint, &acf);
3348fc6c2d82c1f30ff82274334c01f0799def6a609joshualitt        if (NULL == target) {
3358fc6c2d82c1f30ff82274334c01f0799def6a609joshualitt            return;
3368fc6c2d82c1f30ff82274334c01f0799def6a609joshualitt        }
3378fc6c2d82c1f30ff82274334c01f0799def6a609joshualitt
3388fc6c2d82c1f30ff82274334c01f0799def6a609joshualitt        GR_CREATE_TRACE_MARKER("GrContext::drawPaintWithPerspective", target);
33944701df5ce572ac3cccec785cf52103d3d5d14a5joshualitt        target->drawRect(&pipelineBuilder,
34044701df5ce572ac3cccec785cf52103d3d5d14a5joshualitt                         paint->getColor(),
34144701df5ce572ac3cccec785cf52103d3d5d14a5joshualitt                         SkMatrix::I(),
34244701df5ce572ac3cccec785cf52103d3d5d14a5joshualitt                         r,
34344701df5ce572ac3cccec785cf52103d3d5d14a5joshualitt                         NULL,
34444701df5ce572ac3cccec785cf52103d3d5d14a5joshualitt                         &localMatrix);
34527847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com    }
34627847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com}
34727847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com
348205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com////////////////////////////////////////////////////////////////////////////////
349205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com
350c30aaa0e40a2957b847910f80665616e0d103d50bsalomonstatic inline bool is_irect(const SkRect& r) {
35138406c82b913350e55fa04af8c1941cd9b4aff52tfarina  return SkScalarIsInt(r.fLeft)  && SkScalarIsInt(r.fTop) &&
35238406c82b913350e55fa04af8c1941cd9b4aff52tfarina         SkScalarIsInt(r.fRight) && SkScalarIsInt(r.fBottom);
353c30aaa0e40a2957b847910f80665616e0d103d50bsalomon}
354c30aaa0e40a2957b847910f80665616e0d103d50bsalomon
355205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.comstatic bool apply_aa_to_rect(GrDrawTarget* target,
3568dd688b7569df569a672a8a67b2db86a9d376cfcegdaniel                             GrPipelineBuilder* pipelineBuilder,
3579853ccef19c200be93a6211f32589fa82a53067cjoshualitt                             SkRect* devBoundRect,
358fd03d4a829efe2d77a712fd991927c55f59a2ffecommit-bot@chromium.org                             const SkRect& rect,
359df3695e5c72b3b4401e71ff259827d87bfe8a06frobertphillips@google.com                             SkScalar strokeWidth,
3602e3b3e369d79e78f7635d4c20e83a47ab571bdf2joshualitt                             const SkMatrix& combinedMatrix,
3612e3b3e369d79e78f7635d4c20e83a47ab571bdf2joshualitt                             GrColor color) {
3628dd688b7569df569a672a8a67b2db86a9d376cfcegdaniel    if (pipelineBuilder->getRenderTarget()->isMultisampled()) {
363205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com        return false;
364205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com    }
365205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com
3664b140b5fbedcb75d0b9587fa9d232ce54d9c7eb5robertphillips@google.com#if defined(SHADER_AA_FILL_RECT) || !defined(IGNORE_ROT_AA_RECT_OPT)
367df3695e5c72b3b4401e71ff259827d87bfe8a06frobertphillips@google.com    if (strokeWidth >= 0) {
368df3695e5c72b3b4401e71ff259827d87bfe8a06frobertphillips@google.com#endif
36924ab3b0ce50b3428f063849b6160e468f047487ccommit-bot@chromium.org        if (!combinedMatrix.preservesAxisAlignment()) {
370df3695e5c72b3b4401e71ff259827d87bfe8a06frobertphillips@google.com            return false;
371df3695e5c72b3b4401e71ff259827d87bfe8a06frobertphillips@google.com        }
372205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com
3734b140b5fbedcb75d0b9587fa9d232ce54d9c7eb5robertphillips@google.com#if defined(SHADER_AA_FILL_RECT) || !defined(IGNORE_ROT_AA_RECT_OPT)
374df3695e5c72b3b4401e71ff259827d87bfe8a06frobertphillips@google.com    } else {
37524ab3b0ce50b3428f063849b6160e468f047487ccommit-bot@chromium.org        if (!combinedMatrix.preservesRightAngles()) {
376df3695e5c72b3b4401e71ff259827d87bfe8a06frobertphillips@google.com            return false;
377df3695e5c72b3b4401e71ff259827d87bfe8a06frobertphillips@google.com        }
378205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com    }
379df3695e5c72b3b4401e71ff259827d87bfe8a06frobertphillips@google.com#endif
380205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com
38124ab3b0ce50b3428f063849b6160e468f047487ccommit-bot@chromium.org    combinedMatrix.mapRect(devBoundRect, rect);
382e638d1c29b2895a4dcf41b5bc8868278192bf819derekf    if (!combinedMatrix.rectStaysRect()) {
383e638d1c29b2895a4dcf41b5bc8868278192bf819derekf        return true;
384e638d1c29b2895a4dcf41b5bc8868278192bf819derekf    }
385e638d1c29b2895a4dcf41b5bc8868278192bf819derekf
386c30aaa0e40a2957b847910f80665616e0d103d50bsalomon    if (strokeWidth < 0) {
387c30aaa0e40a2957b847910f80665616e0d103d50bsalomon        return !is_irect(*devBoundRect);
388c30aaa0e40a2957b847910f80665616e0d103d50bsalomon    }
38928ac96e40d705f7fb08a61ac027e15de8d91823crobertphillips@google.com
3909c0822a4150e23cec9f9b72bd1abc2c5f9ea5a3bbsalomon    return true;
391205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com}
392205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com
39324ab3b0ce50b3428f063849b6160e468f047487ccommit-bot@chromium.orgstatic inline bool rect_contains_inclusive(const SkRect& rect, const SkPoint& point) {
39424ab3b0ce50b3428f063849b6160e468f047487ccommit-bot@chromium.org    return point.fX >= rect.fLeft && point.fX <= rect.fRight &&
39524ab3b0ce50b3428f063849b6160e468f047487ccommit-bot@chromium.org           point.fY >= rect.fTop && point.fY <= rect.fBottom;
39624ab3b0ce50b3428f063849b6160e468f047487ccommit-bot@chromium.org}
39724ab3b0ce50b3428f063849b6160e468f047487ccommit-bot@chromium.org
3980823bfae151dd27f364db3a7f07017a7cef6bfddjoshualittclass StrokeRectBatch : public GrBatch {
3990823bfae151dd27f364db3a7f07017a7cef6bfddjoshualittpublic:
4000823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt    struct Geometry {
4010823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt        GrColor fColor;
4020823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt        SkMatrix fViewMatrix;
4030823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt        SkRect fRect;
4040823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt        SkScalar fStrokeWidth;
4050823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt    };
4060823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt
4074c977868bbe100d6d95f9e53cf176d611eceb3dcjoshualitt    static GrBatch* Create(const Geometry& geometry, bool snapToPixelCenters) {
4084c977868bbe100d6d95f9e53cf176d611eceb3dcjoshualitt        return SkNEW_ARGS(StrokeRectBatch, (geometry, snapToPixelCenters));
4090823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt    }
4100823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt
41136352bf5e38f45a70ee4f4fc132a38048d38206dmtklein    const char* name() const override { return "StrokeRectBatch"; }
4120823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt
41336352bf5e38f45a70ee4f4fc132a38048d38206dmtklein    void getInvariantOutputColor(GrInitInvariantOutput* out) const override {
4140823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt        // When this is called on a batch, there is only one geometry bundle
4150823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt        out->setKnownFourComponents(fGeoData[0].fColor);
4160823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt    }
4170823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt
41836352bf5e38f45a70ee4f4fc132a38048d38206dmtklein    void getInvariantOutputCoverage(GrInitInvariantOutput* out) const override {
4190823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt        out->setKnownSingleComponent(0xff);
4200823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt    }
4210823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt
42236352bf5e38f45a70ee4f4fc132a38048d38206dmtklein    void initBatchTracker(const GrPipelineInfo& init) override {
4230823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt        // Handle any color overrides
4240823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt        if (init.fColorIgnored) {
4250823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt            fGeoData[0].fColor = GrColor_ILLEGAL;
4260823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt        } else if (GrColor_ILLEGAL != init.fOverrideColor) {
4270823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt            fGeoData[0].fColor = init.fOverrideColor;
4280823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt        }
4290823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt
4300823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt        // setup batch properties
4310823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt        fBatch.fColorIgnored = init.fColorIgnored;
4320823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt        fBatch.fColor = fGeoData[0].fColor;
4330823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt        fBatch.fUsesLocalCoords = init.fUsesLocalCoords;
4340823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt        fBatch.fCoverageIgnored = init.fCoverageIgnored;
4350823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt    }
4360823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt
43736352bf5e38f45a70ee4f4fc132a38048d38206dmtklein    void generateGeometry(GrBatchTarget* batchTarget, const GrPipeline* pipeline) override {
4380823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt        SkAutoTUnref<const GrGeometryProcessor> gp(
4390823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt                GrDefaultGeoProcFactory::Create(GrDefaultGeoProcFactory::kPosition_GPType,
4400823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt                                                this->color(),
4410823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt                                                this->viewMatrix(),
4420823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt                                                SkMatrix::I()));
4430823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt
4440823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt        batchTarget->initDraw(gp, pipeline);
4450823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt
4460823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt        // TODO this is hacky, but the only way we have to initialize the GP is to use the
4470823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt        // GrPipelineInfo struct so we can generate the correct shader.  Once we have GrBatch
4480823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt        // everywhere we can remove this nastiness
4490823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt        GrPipelineInfo init;
4500823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt        init.fColorIgnored = fBatch.fColorIgnored;
4510823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt        init.fOverrideColor = GrColor_ILLEGAL;
4520823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt        init.fCoverageIgnored = fBatch.fCoverageIgnored;
4530823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt        init.fUsesLocalCoords = this->usesLocalCoords();
4540823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt        gp->initBatchTracker(batchTarget->currentBatchTracker(), init);
4550823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt
4560823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt        size_t vertexStride = gp->getVertexStride();
4570823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt
4580823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt        SkASSERT(vertexStride == sizeof(GrDefaultGeoProcFactory::PositionAttr));
4590823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt
4600823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt        Geometry& args = fGeoData[0];
4610823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt
4620823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt        int vertexCount = kVertsPerHairlineRect;
4630823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt        if (args.fStrokeWidth > 0) {
4640823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt            vertexCount = kVertsPerStrokeRect;
4650823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt        }
4660823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt
4670823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt        const GrVertexBuffer* vertexBuffer;
4680823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt        int firstVertex;
4690823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt
470e40d39725908d99d255496025411e5c9ca32663erobertphillips        void* verts = batchTarget->makeVertSpace(vertexStride, vertexCount,
471e40d39725908d99d255496025411e5c9ca32663erobertphillips                                                 &vertexBuffer, &firstVertex);
4720823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt
473cb8979d088a66ebaf41f10ba6f5c830615aa0e03bsalomon        if (!verts) {
4744b31de8328bbf3ee789157ae1dc6fe7cc74c796ajoshualitt            SkDebugf("Could not allocate vertices\n");
4754b31de8328bbf3ee789157ae1dc6fe7cc74c796ajoshualitt            return;
4764b31de8328bbf3ee789157ae1dc6fe7cc74c796ajoshualitt        }
4774b31de8328bbf3ee789157ae1dc6fe7cc74c796ajoshualitt
478cb8979d088a66ebaf41f10ba6f5c830615aa0e03bsalomon        SkPoint* vertex = reinterpret_cast<SkPoint*>(verts);
4790823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt
4800823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt        GrPrimitiveType primType;
4810823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt
4820823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt        if (args.fStrokeWidth > 0) {;
4830823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt            primType = kTriangleStrip_GrPrimitiveType;
4840823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt            args.fRect.sort();
4850823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt            this->setStrokeRectStrip(vertex, args.fRect, args.fStrokeWidth);
4860823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt        } else {
4870823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt            // hairline
4880823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt            primType = kLineStrip_GrPrimitiveType;
4890823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt            vertex[0].set(args.fRect.fLeft, args.fRect.fTop);
4900823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt            vertex[1].set(args.fRect.fRight, args.fRect.fTop);
4910823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt            vertex[2].set(args.fRect.fRight, args.fRect.fBottom);
4920823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt            vertex[3].set(args.fRect.fLeft, args.fRect.fBottom);
4930823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt            vertex[4].set(args.fRect.fLeft, args.fRect.fTop);
4940823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt        }
4950823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt
496cb8979d088a66ebaf41f10ba6f5c830615aa0e03bsalomon        GrVertices vertices;
497cb8979d088a66ebaf41f10ba6f5c830615aa0e03bsalomon        vertices.init(primType, vertexBuffer, firstVertex, vertexCount);
498cb8979d088a66ebaf41f10ba6f5c830615aa0e03bsalomon        batchTarget->draw(vertices);
4990823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt    }
5000823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt
5010823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt    SkSTArray<1, Geometry, true>* geoData() { return &fGeoData; }
5020823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt
5030823bfae151dd27f364db3a7f07017a7cef6bfddjoshualittprivate:
5044c977868bbe100d6d95f9e53cf176d611eceb3dcjoshualitt    StrokeRectBatch(const Geometry& geometry, bool snapToPixelCenters) {
5050823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt        this->initClassID<StrokeRectBatch>();
5060823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt
5070823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt        fBatch.fHairline = geometry.fStrokeWidth == 0;
5080823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt
5090823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt        fGeoData.push_back(geometry);
51099c7c07e0f1f7b78980eb21d84bebda8b45a7178joshualitt
51199c7c07e0f1f7b78980eb21d84bebda8b45a7178joshualitt        // setup bounds
51299c7c07e0f1f7b78980eb21d84bebda8b45a7178joshualitt        fBounds = geometry.fRect;
51399c7c07e0f1f7b78980eb21d84bebda8b45a7178joshualitt        SkScalar rad = SkScalarHalf(geometry.fStrokeWidth);
51499c7c07e0f1f7b78980eb21d84bebda8b45a7178joshualitt        fBounds.outset(rad, rad);
51599c7c07e0f1f7b78980eb21d84bebda8b45a7178joshualitt        geometry.fViewMatrix.mapRect(&fBounds);
5164c977868bbe100d6d95f9e53cf176d611eceb3dcjoshualitt
5174c977868bbe100d6d95f9e53cf176d611eceb3dcjoshualitt        // If our caller snaps to pixel centers then we have to round out the bounds
5184c977868bbe100d6d95f9e53cf176d611eceb3dcjoshualitt        if (snapToPixelCenters) {
5194c977868bbe100d6d95f9e53cf176d611eceb3dcjoshualitt            fBounds.roundOut();
5204c977868bbe100d6d95f9e53cf176d611eceb3dcjoshualitt        }
5210823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt    }
5220823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt
5230823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt    /*  create a triangle strip that strokes the specified rect. There are 8
5240823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt     unique vertices, but we repeat the last 2 to close up. Alternatively we
5250823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt     could use an indices array, and then only send 8 verts, but not sure that
5260823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt     would be faster.
5270823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt     */
5280823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt    void setStrokeRectStrip(SkPoint verts[10], const SkRect& rect, SkScalar width) {
5290823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt        const SkScalar rad = SkScalarHalf(width);
5300823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt        // TODO we should be able to enable this assert, but we'd have to filter these draws
5310823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt        // this is a bug
5320823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt        //SkASSERT(rad < rect.width() / 2 && rad < rect.height() / 2);
5330823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt
5340823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt        verts[0].set(rect.fLeft + rad, rect.fTop + rad);
5350823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt        verts[1].set(rect.fLeft - rad, rect.fTop - rad);
5360823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt        verts[2].set(rect.fRight - rad, rect.fTop + rad);
5370823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt        verts[3].set(rect.fRight + rad, rect.fTop - rad);
5380823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt        verts[4].set(rect.fRight - rad, rect.fBottom - rad);
5390823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt        verts[5].set(rect.fRight + rad, rect.fBottom + rad);
5400823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt        verts[6].set(rect.fLeft + rad, rect.fBottom - rad);
5410823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt        verts[7].set(rect.fLeft - rad, rect.fBottom + rad);
5420823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt        verts[8] = verts[0];
5430823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt        verts[9] = verts[1];
5440823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt    }
5450823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt
5460823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt
5470823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt    GrColor color() const { return fBatch.fColor; }
5480823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt    bool usesLocalCoords() const { return fBatch.fUsesLocalCoords; }
5490823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt    bool colorIgnored() const { return fBatch.fColorIgnored; }
5500823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt    const SkMatrix& viewMatrix() const { return fGeoData[0].fViewMatrix; }
5510823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt    bool hairline() const { return fBatch.fHairline; }
5520823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt
55336352bf5e38f45a70ee4f4fc132a38048d38206dmtklein    bool onCombineIfPossible(GrBatch* t) override {
5540823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt        // StrokeRectBatch* that = t->cast<StrokeRectBatch>();
5550823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt
5560823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt        // NonAA stroke rects cannot batch right now
5570823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt        // TODO make these batchable
5580823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt        return false;
5590823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt    }
5600823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt
5610823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt    struct BatchTracker {
5620823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt        GrColor fColor;
5630823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt        bool fUsesLocalCoords;
5640823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt        bool fColorIgnored;
5650823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt        bool fCoverageIgnored;
5660823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt        bool fHairline;
5670823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt    };
5680823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt
5690823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt    const static int kVertsPerHairlineRect = 5;
5700823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt    const static int kVertsPerStrokeRect = 10;
5710823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt
5720823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt    BatchTracker fBatch;
5730823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt    SkSTArray<1, Geometry, true> fGeoData;
5740823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt};
5750823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt
57625d9c154087d2132a51d1ca74a104726f60ef380joshualittvoid GrContext::drawRect(GrRenderTarget* rt,
577570d2f81a65fc868d6300a7edf34c0d5d048c5d6joshualitt                         const GrClip& clip,
57825d9c154087d2132a51d1ca74a104726f60ef380joshualitt                         const GrPaint& paint,
5795531d51ce7426bdae7563547326fcf0bf926a083joshualitt                         const SkMatrix& viewMatrix,
580fd03d4a829efe2d77a712fd991927c55f59a2ffecommit-bot@chromium.org                         const SkRect& rect,
58101c8da1eef36570374f7e8764a38b25bf16ab7a6bsalomon                         const GrStrokeInfo* strokeInfo) {
5825f5a8d7599b8e248633ac122294b7a01401fedcbjoshualitt    RETURN_IF_ABANDONED
58349f085dddff10473b6ebf832a974288300224e60bsalomon    if (strokeInfo && strokeInfo->isDashed()) {
584d58a0ba9cff9fcefe5047e88ccb4a6e76c591c40egdaniel        SkPath path;
585d58a0ba9cff9fcefe5047e88ccb4a6e76c591c40egdaniel        path.addRect(rect);
586570d2f81a65fc868d6300a7edf34c0d5d048c5d6joshualitt        this->drawPath(rt, clip, paint, viewMatrix, path, *strokeInfo);
587d58a0ba9cff9fcefe5047e88ccb4a6e76c591c40egdaniel        return;
588d58a0ba9cff9fcefe5047e88ccb4a6e76c591c40egdaniel    }
589d58a0ba9cff9fcefe5047e88ccb4a6e76c591c40egdaniel
590f21dab95405979a4aff9f6a741c818304a67f220bsalomon    AutoCheckFlush acf(this);
5918dd688b7569df569a672a8a67b2db86a9d376cfcegdaniel    GrPipelineBuilder pipelineBuilder;
592570d2f81a65fc868d6300a7edf34c0d5d048c5d6joshualitt    GrDrawTarget* target = this->prepareToDraw(&pipelineBuilder, rt, clip, &paint, &acf);
59341ebbddd76b747d5fb32c02dda0de3d03a3edda5bsalomon    if (NULL == target) {
59441ebbddd76b747d5fb32c02dda0de3d03a3edda5bsalomon        return;
59541ebbddd76b747d5fb32c02dda0de3d03a3edda5bsalomon    }
59627847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com
5972a05de0c049a8648942a55016126a1f92e1c14d6commit-bot@chromium.org    GR_CREATE_TRACE_MARKER("GrContext::drawRect", target);
598d58a0ba9cff9fcefe5047e88ccb4a6e76c591c40egdaniel    SkScalar width = NULL == strokeInfo ? -1 : strokeInfo->getStrokeRec().getWidth();
59924ab3b0ce50b3428f063849b6160e468f047487ccommit-bot@chromium.org
60024ab3b0ce50b3428f063849b6160e468f047487ccommit-bot@chromium.org    // Check if this is a full RT draw and can be replaced with a clear. We don't bother checking
60124ab3b0ce50b3428f063849b6160e468f047487ccommit-bot@chromium.org    // cases where the RT is fully inside a stroke.
60224ab3b0ce50b3428f063849b6160e468f047487ccommit-bot@chromium.org    if (width < 0) {
60324ab3b0ce50b3428f063849b6160e468f047487ccommit-bot@chromium.org        SkRect rtRect;
6048dd688b7569df569a672a8a67b2db86a9d376cfcegdaniel        pipelineBuilder.getRenderTarget()->getBoundsRect(&rtRect);
60524ab3b0ce50b3428f063849b6160e468f047487ccommit-bot@chromium.org        SkRect clipSpaceRTRect = rtRect;
606570d2f81a65fc868d6300a7edf34c0d5d048c5d6joshualitt        bool checkClip = GrClip::kWideOpen_ClipType != clip.clipType();
60744701df5ce572ac3cccec785cf52103d3d5d14a5joshualitt        if (checkClip) {
608570d2f81a65fc868d6300a7edf34c0d5d048c5d6joshualitt            clipSpaceRTRect.offset(SkIntToScalar(clip.origin().fX),
609570d2f81a65fc868d6300a7edf34c0d5d048c5d6joshualitt                                   SkIntToScalar(clip.origin().fY));
61024ab3b0ce50b3428f063849b6160e468f047487ccommit-bot@chromium.org        }
61124ab3b0ce50b3428f063849b6160e468f047487ccommit-bot@chromium.org        // Does the clip contain the entire RT?
612570d2f81a65fc868d6300a7edf34c0d5d048c5d6joshualitt        if (!checkClip || clip.quickContains(clipSpaceRTRect)) {
61324ab3b0ce50b3428f063849b6160e468f047487ccommit-bot@chromium.org            SkMatrix invM;
6148059eb9f6e24ed609393fbda4ad71edea03ac258joshualitt            if (!viewMatrix.invert(&invM)) {
61524ab3b0ce50b3428f063849b6160e468f047487ccommit-bot@chromium.org                return;
61624ab3b0ce50b3428f063849b6160e468f047487ccommit-bot@chromium.org            }
61724ab3b0ce50b3428f063849b6160e468f047487ccommit-bot@chromium.org            // Does the rect bound the RT?
61824ab3b0ce50b3428f063849b6160e468f047487ccommit-bot@chromium.org            SkPoint srcSpaceRTQuad[4];
61924ab3b0ce50b3428f063849b6160e468f047487ccommit-bot@chromium.org            invM.mapRectToQuad(srcSpaceRTQuad, rtRect);
62024ab3b0ce50b3428f063849b6160e468f047487ccommit-bot@chromium.org            if (rect_contains_inclusive(rect, srcSpaceRTQuad[0]) &&
62124ab3b0ce50b3428f063849b6160e468f047487ccommit-bot@chromium.org                rect_contains_inclusive(rect, srcSpaceRTQuad[1]) &&
62224ab3b0ce50b3428f063849b6160e468f047487ccommit-bot@chromium.org                rect_contains_inclusive(rect, srcSpaceRTQuad[2]) &&
62324ab3b0ce50b3428f063849b6160e468f047487ccommit-bot@chromium.org                rect_contains_inclusive(rect, srcSpaceRTQuad[3])) {
62424ab3b0ce50b3428f063849b6160e468f047487ccommit-bot@chromium.org                // Will it blend?
62524ab3b0ce50b3428f063849b6160e468f047487ccommit-bot@chromium.org                GrColor clearColor;
62624ab3b0ce50b3428f063849b6160e468f047487ccommit-bot@chromium.org                if (paint.isOpaqueAndConstantColor(&clearColor)) {
62725d9c154087d2132a51d1ca74a104726f60ef380joshualitt                    target->clear(NULL, clearColor, true, rt);
62824ab3b0ce50b3428f063849b6160e468f047487ccommit-bot@chromium.org                    return;
62924ab3b0ce50b3428f063849b6160e468f047487ccommit-bot@chromium.org                }
63024ab3b0ce50b3428f063849b6160e468f047487ccommit-bot@chromium.org            }
63124ab3b0ce50b3428f063849b6160e468f047487ccommit-bot@chromium.org        }
63224ab3b0ce50b3428f063849b6160e468f047487ccommit-bot@chromium.org    }
63324ab3b0ce50b3428f063849b6160e468f047487ccommit-bot@chromium.org
6342e3b3e369d79e78f7635d4c20e83a47ab571bdf2joshualitt    GrColor color = paint.getColor();
63524ab3b0ce50b3428f063849b6160e468f047487ccommit-bot@chromium.org    SkRect devBoundRect;
6368dd688b7569df569a672a8a67b2db86a9d376cfcegdaniel    bool needAA = paint.isAntiAlias() && !pipelineBuilder.getRenderTarget()->isMultisampled();
6378dd688b7569df569a672a8a67b2db86a9d376cfcegdaniel    bool doAA = needAA && apply_aa_to_rect(target, &pipelineBuilder, &devBoundRect, rect, width,
6388059eb9f6e24ed609393fbda4ad71edea03ac258joshualitt                                           viewMatrix, color);
639d58a0ba9cff9fcefe5047e88ccb4a6e76c591c40egdaniel
640205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com    if (doAA) {
641205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com        if (width >= 0) {
642395ef0568dac793020f66cbec4b6ef86736d4db0bsalomon            const SkStrokeRec& strokeRec = strokeInfo->getStrokeRec();
6439853ccef19c200be93a6211f32589fa82a53067cjoshualitt            fAARectRenderer->strokeAARect(target,
6448dd688b7569df569a672a8a67b2db86a9d376cfcegdaniel                                          &pipelineBuilder,
6452e3b3e369d79e78f7635d4c20e83a47ab571bdf2joshualitt                                          color,
6468059eb9f6e24ed609393fbda4ad71edea03ac258joshualitt                                          viewMatrix,
6479853ccef19c200be93a6211f32589fa82a53067cjoshualitt                                          rect,
6489853ccef19c200be93a6211f32589fa82a53067cjoshualitt                                          devBoundRect,
6499853ccef19c200be93a6211f32589fa82a53067cjoshualitt                                          strokeRec);
650205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com        } else {
651df3695e5c72b3b4401e71ff259827d87bfe8a06frobertphillips@google.com            // filled AA rect
6528059eb9f6e24ed609393fbda4ad71edea03ac258joshualitt            fAARectRenderer->fillAARect(target,
6538dd688b7569df569a672a8a67b2db86a9d376cfcegdaniel                                        &pipelineBuilder,
6548059eb9f6e24ed609393fbda4ad71edea03ac258joshualitt                                        color,
6558059eb9f6e24ed609393fbda4ad71edea03ac258joshualitt                                        viewMatrix,
6568059eb9f6e24ed609393fbda4ad71edea03ac258joshualitt                                        rect,
657d27f73ef27ff65a6a0a5d00aa8e5b784b1a0b47ejoshualitt                                        devBoundRect);
658205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com        }
659205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com        return;
660205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com    }
661205d46067ace24bd4b111cf44efc96caff6c4d30bsalomon@google.com
66227847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com    if (width >= 0) {
6630823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt        StrokeRectBatch::Geometry geometry;
6640823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt        geometry.fViewMatrix = viewMatrix;
6650823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt        geometry.fColor = color;
6660823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt        geometry.fRect = rect;
6670823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt        geometry.fStrokeWidth = width;
6680823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt
6694c977868bbe100d6d95f9e53cf176d611eceb3dcjoshualitt        // Non-AA hairlines are snapped to pixel centers to make which pixels are hit deterministic
6704c977868bbe100d6d95f9e53cf176d611eceb3dcjoshualitt        bool snapToPixelCenters = (0 == width && !rt->isMultisampled());
6714c977868bbe100d6d95f9e53cf176d611eceb3dcjoshualitt        SkAutoTUnref<GrBatch> batch(StrokeRectBatch::Create(geometry, snapToPixelCenters));
6720823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt
673d79c549467e5e7be025e38357f179b7965ed2ec3bsalomon        // Depending on sub-pixel coordinates and the particular GPU, we may lose a corner of
674d79c549467e5e7be025e38357f179b7965ed2ec3bsalomon        // hairline rects. We jam all the vertices to pixel centers to avoid this, but not when MSAA
675d79c549467e5e7be025e38357f179b7965ed2ec3bsalomon        // is enabled because it can cause ugly artifacts.
676d79c549467e5e7be025e38357f179b7965ed2ec3bsalomon        pipelineBuilder.setState(GrPipelineBuilder::kSnapVerticesToPixelCenters_Flag,
6774c977868bbe100d6d95f9e53cf176d611eceb3dcjoshualitt                                 snapToPixelCenters);
67899c7c07e0f1f7b78980eb21d84bebda8b45a7178joshualitt        target->drawBatch(&pipelineBuilder, batch);
67927847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com    } else {
680df3695e5c72b3b4401e71ff259827d87bfe8a06frobertphillips@google.com        // filled BW rect
6818dd688b7569df569a672a8a67b2db86a9d376cfcegdaniel        target->drawSimpleRect(&pipelineBuilder, color, viewMatrix, rect);
68227847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com    }
68327847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com}
68427847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com
68525d9c154087d2132a51d1ca74a104726f60ef380joshualittvoid GrContext::drawNonAARectToRect(GrRenderTarget* rt,
686570d2f81a65fc868d6300a7edf34c0d5d048c5d6joshualitt                                    const GrClip& clip,
68725d9c154087d2132a51d1ca74a104726f60ef380joshualitt                                    const GrPaint& paint,
68816b278989532ee9f9a38e3eb4754b228ff495cb8joshualitt                                    const SkMatrix& viewMatrix,
68916b278989532ee9f9a38e3eb4754b228ff495cb8joshualitt                                    const SkRect& rectToDraw,
69016b278989532ee9f9a38e3eb4754b228ff495cb8joshualitt                                    const SkRect& localRect,
69116b278989532ee9f9a38e3eb4754b228ff495cb8joshualitt                                    const SkMatrix* localMatrix) {
6925f5a8d7599b8e248633ac122294b7a01401fedcbjoshualitt    RETURN_IF_ABANDONED
693f21dab95405979a4aff9f6a741c818304a67f220bsalomon    AutoCheckFlush acf(this);
6948dd688b7569df569a672a8a67b2db86a9d376cfcegdaniel    GrPipelineBuilder pipelineBuilder;
695570d2f81a65fc868d6300a7edf34c0d5d048c5d6joshualitt    GrDrawTarget* target = this->prepareToDraw(&pipelineBuilder, rt, clip, &paint, &acf);
69641ebbddd76b747d5fb32c02dda0de3d03a3edda5bsalomon    if (NULL == target) {
69741ebbddd76b747d5fb32c02dda0de3d03a3edda5bsalomon        return;
69841ebbddd76b747d5fb32c02dda0de3d03a3edda5bsalomon    }
6996438695222333981fafee9c8c09f3bf51dce3816bsalomon@google.com
7002a05de0c049a8648942a55016126a1f92e1c14d6commit-bot@chromium.org    GR_CREATE_TRACE_MARKER("GrContext::drawRectToRect", target);
7012a05de0c049a8648942a55016126a1f92e1c14d6commit-bot@chromium.org
70244701df5ce572ac3cccec785cf52103d3d5d14a5joshualitt    target->drawRect(&pipelineBuilder,
70344701df5ce572ac3cccec785cf52103d3d5d14a5joshualitt                     paint.getColor(),
70444701df5ce572ac3cccec785cf52103d3d5d14a5joshualitt                     viewMatrix,
70544701df5ce572ac3cccec785cf52103d3d5d14a5joshualitt                     rectToDraw,
70644701df5ce572ac3cccec785cf52103d3d5d14a5joshualitt                     &localRect,
7078dd688b7569df569a672a8a67b2db86a9d376cfcegdaniel                     localMatrix);
70827847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com}
70927847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com
7100823bfae151dd27f364db3a7f07017a7cef6bfddjoshualittstatic const GrGeometryProcessor* set_vertex_attributes(bool hasLocalCoords,
7110823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt                                                        bool hasColors,
71256995b5cc00c9c83bd5fcf86bca9a67e939a96cbjoshualitt                                                        int* colorOffset,
71356995b5cc00c9c83bd5fcf86bca9a67e939a96cbjoshualitt                                                        int* texOffset,
7148059eb9f6e24ed609393fbda4ad71edea03ac258joshualitt                                                        GrColor color,
7158059eb9f6e24ed609393fbda4ad71edea03ac258joshualitt                                                        const SkMatrix& viewMatrix) {
716429033038271147ed66b4bc2675ac98a5ccfa75crobertphillips@google.com    *texOffset = -1;
717429033038271147ed66b4bc2675ac98a5ccfa75crobertphillips@google.com    *colorOffset = -1;
7185478d427c6e67c986a3390162c8fec77c466058ajoshualitt    uint32_t flags = GrDefaultGeoProcFactory::kPosition_GPType;
7190823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt    if (hasLocalCoords && hasColors) {
7205478d427c6e67c986a3390162c8fec77c466058ajoshualitt        *colorOffset = sizeof(SkPoint);
7215478d427c6e67c986a3390162c8fec77c466058ajoshualitt        *texOffset = sizeof(SkPoint) + sizeof(GrColor);
7225478d427c6e67c986a3390162c8fec77c466058ajoshualitt        flags |= GrDefaultGeoProcFactory::kColor_GPType |
7235478d427c6e67c986a3390162c8fec77c466058ajoshualitt                 GrDefaultGeoProcFactory::kLocalCoord_GPType;
7240823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt    } else if (hasLocalCoords) {
725972f9cd7a063d0544f8c919fd12b9a3adbd12b24commit-bot@chromium.org        *texOffset = sizeof(SkPoint);
7265478d427c6e67c986a3390162c8fec77c466058ajoshualitt        flags |= GrDefaultGeoProcFactory::kLocalCoord_GPType;
7270823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt    } else if (hasColors) {
728972f9cd7a063d0544f8c919fd12b9a3adbd12b24commit-bot@chromium.org        *colorOffset = sizeof(SkPoint);
7295478d427c6e67c986a3390162c8fec77c466058ajoshualitt        flags |= GrDefaultGeoProcFactory::kColor_GPType;
730429033038271147ed66b4bc2675ac98a5ccfa75crobertphillips@google.com    }
7318059eb9f6e24ed609393fbda4ad71edea03ac258joshualitt    return GrDefaultGeoProcFactory::Create(flags, color, viewMatrix, SkMatrix::I());
732429033038271147ed66b4bc2675ac98a5ccfa75crobertphillips@google.com}
733429033038271147ed66b4bc2675ac98a5ccfa75crobertphillips@google.com
7340823bfae151dd27f364db3a7f07017a7cef6bfddjoshualittclass DrawVerticesBatch : public GrBatch {
7350823bfae151dd27f364db3a7f07017a7cef6bfddjoshualittpublic:
7360823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt    struct Geometry {
7370823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt        GrColor fColor;
7380823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt        SkTDArray<SkPoint> fPositions;
7390823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt        SkTDArray<uint16_t> fIndices;
7400823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt        SkTDArray<GrColor> fColors;
7410823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt        SkTDArray<SkPoint> fLocalCoords;
7420823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt    };
7430823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt
7440823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt    static GrBatch* Create(const Geometry& geometry, GrPrimitiveType primitiveType,
7450823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt                           const SkMatrix& viewMatrix,
7460823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt                           const SkPoint* positions, int vertexCount,
7470823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt                           const uint16_t* indices, int indexCount,
74899c7c07e0f1f7b78980eb21d84bebda8b45a7178joshualitt                           const GrColor* colors, const SkPoint* localCoords,
74999c7c07e0f1f7b78980eb21d84bebda8b45a7178joshualitt                           const SkRect& bounds) {
7500823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt        return SkNEW_ARGS(DrawVerticesBatch, (geometry, primitiveType, viewMatrix, positions,
7510823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt                                              vertexCount, indices, indexCount, colors,
75299c7c07e0f1f7b78980eb21d84bebda8b45a7178joshualitt                                              localCoords, bounds));
7530823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt    }
7540823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt
75536352bf5e38f45a70ee4f4fc132a38048d38206dmtklein    const char* name() const override { return "DrawVerticesBatch"; }
7560823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt
75736352bf5e38f45a70ee4f4fc132a38048d38206dmtklein    void getInvariantOutputColor(GrInitInvariantOutput* out) const override {
7580823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt        // When this is called on a batch, there is only one geometry bundle
7590823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt        if (this->hasColors()) {
7600823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt            out->setUnknownFourComponents();
7610823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt        } else {
7620823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt            out->setKnownFourComponents(fGeoData[0].fColor);
7630823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt        }
7640823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt    }
7650823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt
76636352bf5e38f45a70ee4f4fc132a38048d38206dmtklein    void getInvariantOutputCoverage(GrInitInvariantOutput* out) const override {
767d4c7d55594d94a00b6cecf6b2fdbb811836ce2ffjoshualitt        out->setKnownSingleComponent(0xff);
7680823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt    }
7690823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt
77036352bf5e38f45a70ee4f4fc132a38048d38206dmtklein    void initBatchTracker(const GrPipelineInfo& init) override {
7710823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt        // Handle any color overrides
7720823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt        if (init.fColorIgnored) {
7730823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt            fGeoData[0].fColor = GrColor_ILLEGAL;
7740823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt        } else if (GrColor_ILLEGAL != init.fOverrideColor) {
7750823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt            fGeoData[0].fColor = init.fOverrideColor;
7760823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt        }
7770823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt
7780823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt        // setup batch properties
7790823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt        fBatch.fColorIgnored = init.fColorIgnored;
7800823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt        fBatch.fColor = fGeoData[0].fColor;
7810823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt        fBatch.fUsesLocalCoords = init.fUsesLocalCoords;
7820823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt        fBatch.fCoverageIgnored = init.fCoverageIgnored;
7830823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt    }
7840823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt
78536352bf5e38f45a70ee4f4fc132a38048d38206dmtklein    void generateGeometry(GrBatchTarget* batchTarget, const GrPipeline* pipeline) override {
7860823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt        int colorOffset = -1, texOffset = -1;
7870823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt        SkAutoTUnref<const GrGeometryProcessor> gp(
7880823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt                set_vertex_attributes(this->hasLocalCoords(), this->hasColors(), &colorOffset,
7890823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt                                      &texOffset, this->color(), this->viewMatrix()));
7900823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt
7910823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt        batchTarget->initDraw(gp, pipeline);
7920823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt
7930823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt        // TODO this is hacky, but the only way we have to initialize the GP is to use the
7940823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt        // GrPipelineInfo struct so we can generate the correct shader.  Once we have GrBatch
7950823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt        // everywhere we can remove this nastiness
7960823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt        GrPipelineInfo init;
7970823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt        init.fColorIgnored = fBatch.fColorIgnored;
7980823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt        init.fOverrideColor = GrColor_ILLEGAL;
7990823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt        init.fCoverageIgnored = fBatch.fCoverageIgnored;
8000823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt        init.fUsesLocalCoords = this->usesLocalCoords();
8010823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt        gp->initBatchTracker(batchTarget->currentBatchTracker(), init);
8020823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt
8030823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt        size_t vertexStride = gp->getVertexStride();
8040823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt
8050823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt        SkASSERT(vertexStride == sizeof(SkPoint) + (this->hasLocalCoords() ? sizeof(SkPoint) : 0)
8060823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt                                                 + (this->hasColors() ? sizeof(GrColor) : 0));
8070823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt
8080823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt        int instanceCount = fGeoData.count();
8090823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt
8100823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt        const GrVertexBuffer* vertexBuffer;
8110823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt        int firstVertex;
8120823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt
813e40d39725908d99d255496025411e5c9ca32663erobertphillips        void* verts = batchTarget->makeVertSpace(vertexStride, this->vertexCount(),
814e40d39725908d99d255496025411e5c9ca32663erobertphillips                                                 &vertexBuffer, &firstVertex);
8150823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt
816cb8979d088a66ebaf41f10ba6f5c830615aa0e03bsalomon        if (!verts) {
8174b31de8328bbf3ee789157ae1dc6fe7cc74c796ajoshualitt            SkDebugf("Could not allocate vertices\n");
8184b31de8328bbf3ee789157ae1dc6fe7cc74c796ajoshualitt            return;
8194b31de8328bbf3ee789157ae1dc6fe7cc74c796ajoshualitt        }
8204b31de8328bbf3ee789157ae1dc6fe7cc74c796ajoshualitt
821b5238a7571c243ba4a154a62575570c3078b3741bsalomon        const GrIndexBuffer* indexBuffer = NULL;
822b5238a7571c243ba4a154a62575570c3078b3741bsalomon        int firstIndex = 0;
8230823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt
824e40d39725908d99d255496025411e5c9ca32663erobertphillips        uint16_t* indices = NULL;
8250823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt        if (this->hasIndices()) {
826e40d39725908d99d255496025411e5c9ca32663erobertphillips            indices = batchTarget->makeIndexSpace(this->indexCount(), &indexBuffer, &firstIndex);
8274b31de8328bbf3ee789157ae1dc6fe7cc74c796ajoshualitt
8284b31de8328bbf3ee789157ae1dc6fe7cc74c796ajoshualitt            if (!indices) {
8294b31de8328bbf3ee789157ae1dc6fe7cc74c796ajoshualitt                SkDebugf("Could not allocate indices\n");
8304b31de8328bbf3ee789157ae1dc6fe7cc74c796ajoshualitt                return;
8314b31de8328bbf3ee789157ae1dc6fe7cc74c796ajoshualitt            }
8320823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt        }
8330823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt
8340823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt        int indexOffset = 0;
8350823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt        int vertexOffset = 0;
8360823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt        for (int i = 0; i < instanceCount; i++) {
8370823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt            const Geometry& args = fGeoData[i];
8380823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt
8390823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt            // TODO we can actually cache this interleaved and then just memcopy
8400823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt            if (this->hasIndices()) {
8410823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt                for (int j = 0; j < args.fIndices.count(); ++j, ++indexOffset) {
842e40d39725908d99d255496025411e5c9ca32663erobertphillips                    *(indices + indexOffset) = args.fIndices[j] + vertexOffset;
8430823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt                }
8440823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt            }
8450823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt
8460823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt            for (int j = 0; j < args.fPositions.count(); ++j) {
847cb8979d088a66ebaf41f10ba6f5c830615aa0e03bsalomon                *((SkPoint*)verts) = args.fPositions[j];
8480823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt                if (this->hasColors()) {
849cb8979d088a66ebaf41f10ba6f5c830615aa0e03bsalomon                    *(GrColor*)((intptr_t)verts + colorOffset) = args.fColors[j];
8500823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt                }
8510823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt                if (this->hasLocalCoords()) {
852cb8979d088a66ebaf41f10ba6f5c830615aa0e03bsalomon                    *(SkPoint*)((intptr_t)verts + texOffset) = args.fLocalCoords[j];
8530823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt                }
854cb8979d088a66ebaf41f10ba6f5c830615aa0e03bsalomon                verts = (void*)((intptr_t)verts + vertexStride);
8550823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt                vertexOffset++;
8560823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt            }
8570823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt        }
8580823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt
859cb8979d088a66ebaf41f10ba6f5c830615aa0e03bsalomon        GrVertices vertices;
8600823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt        if (this->hasIndices()) {
861cb8979d088a66ebaf41f10ba6f5c830615aa0e03bsalomon            vertices.initIndexed(this->primitiveType(), vertexBuffer, indexBuffer, firstVertex,
862b5238a7571c243ba4a154a62575570c3078b3741bsalomon                                 firstIndex, this->vertexCount(), this->indexCount());
863b5238a7571c243ba4a154a62575570c3078b3741bsalomon
8640823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt        } else {
865cb8979d088a66ebaf41f10ba6f5c830615aa0e03bsalomon            vertices.init(this->primitiveType(), vertexBuffer, firstVertex, this->vertexCount());
8660823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt        }
867cb8979d088a66ebaf41f10ba6f5c830615aa0e03bsalomon        batchTarget->draw(vertices);
8680823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt    }
8690823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt
8700823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt    SkSTArray<1, Geometry, true>* geoData() { return &fGeoData; }
8710823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt
8720823bfae151dd27f364db3a7f07017a7cef6bfddjoshualittprivate:
8730823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt    DrawVerticesBatch(const Geometry& geometry, GrPrimitiveType primitiveType,
8740823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt                      const SkMatrix& viewMatrix,
8750823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt                      const SkPoint* positions, int vertexCount,
8760823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt                      const uint16_t* indices, int indexCount,
87799c7c07e0f1f7b78980eb21d84bebda8b45a7178joshualitt                      const GrColor* colors, const SkPoint* localCoords, const SkRect& bounds) {
8780823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt        this->initClassID<DrawVerticesBatch>();
8790823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt        SkASSERT(positions);
8800823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt
8810823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt        fBatch.fViewMatrix = viewMatrix;
8820823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt        Geometry& installedGeo = fGeoData.push_back(geometry);
8830823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt
8840823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt        installedGeo.fPositions.append(vertexCount, positions);
8850823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt        if (indices) {
8860823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt            installedGeo.fIndices.append(indexCount, indices);
8870823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt            fBatch.fHasIndices = true;
8880823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt        } else {
8890823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt            fBatch.fHasIndices = false;
8900823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt        }
8910823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt
8920823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt        if (colors) {
8930823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt            installedGeo.fColors.append(vertexCount, colors);
8940823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt            fBatch.fHasColors = true;
8950823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt        } else {
8960823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt            fBatch.fHasColors = false;
8970823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt        }
8980823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt
8990823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt        if (localCoords) {
9000823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt            installedGeo.fLocalCoords.append(vertexCount, localCoords);
9010823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt            fBatch.fHasLocalCoords = true;
9020823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt        } else {
9030823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt            fBatch.fHasLocalCoords = false;
9040823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt        }
9050823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt        fBatch.fVertexCount = vertexCount;
9060823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt        fBatch.fIndexCount = indexCount;
9070823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt        fBatch.fPrimitiveType = primitiveType;
90899c7c07e0f1f7b78980eb21d84bebda8b45a7178joshualitt
90999c7c07e0f1f7b78980eb21d84bebda8b45a7178joshualitt        this->setBounds(bounds);
9100823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt    }
9110823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt
9120823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt    GrPrimitiveType primitiveType() const { return fBatch.fPrimitiveType; }
9130823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt    bool batchablePrimitiveType() const {
9140823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt        return kTriangles_GrPrimitiveType == fBatch.fPrimitiveType ||
9150823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt               kLines_GrPrimitiveType == fBatch.fPrimitiveType ||
9160823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt               kPoints_GrPrimitiveType == fBatch.fPrimitiveType;
9170823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt    }
9180823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt    GrColor color() const { return fBatch.fColor; }
9190823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt    bool usesLocalCoords() const { return fBatch.fUsesLocalCoords; }
9200823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt    bool colorIgnored() const { return fBatch.fColorIgnored; }
9210823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt    const SkMatrix& viewMatrix() const { return fBatch.fViewMatrix; }
9220823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt    bool hasColors() const { return fBatch.fHasColors; }
9230823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt    bool hasIndices() const { return fBatch.fHasIndices; }
9240823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt    bool hasLocalCoords() const { return fBatch.fHasLocalCoords; }
9250823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt    int vertexCount() const { return fBatch.fVertexCount; }
9260823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt    int indexCount() const { return fBatch.fIndexCount; }
9270823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt
92836352bf5e38f45a70ee4f4fc132a38048d38206dmtklein    bool onCombineIfPossible(GrBatch* t) override {
9290823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt        DrawVerticesBatch* that = t->cast<DrawVerticesBatch>();
9300823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt
9310823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt        if (!this->batchablePrimitiveType() || this->primitiveType() != that->primitiveType()) {
9320823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt            return false;
9330823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt        }
9340823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt
9350823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt        SkASSERT(this->usesLocalCoords() == that->usesLocalCoords());
9360823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt
9370823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt        // We currently use a uniform viewmatrix for this batch
9380823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt        if (!this->viewMatrix().cheapEqualTo(that->viewMatrix())) {
9390823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt            return false;
9400823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt        }
9410823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt
9420823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt        if (this->hasColors() != that->hasColors()) {
9430823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt            return false;
9440823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt        }
9450823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt
9460823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt        if (this->hasIndices() != that->hasIndices()) {
9470823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt            return false;
9480823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt        }
9490823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt
9500823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt        if (this->hasLocalCoords() != that->hasLocalCoords()) {
9510823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt            return false;
9520823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt        }
9530823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt
9540823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt        if (!this->hasColors() && this->color() != that->color()) {
9550823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt            return false;
9560823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt        }
9570823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt
9580823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt        if (this->color() != that->color()) {
9590823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt            fBatch.fColor = GrColor_ILLEGAL;
9600823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt        }
9610823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt        fGeoData.push_back_n(that->geoData()->count(), that->geoData()->begin());
9620823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt        fBatch.fVertexCount += that->vertexCount();
9630823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt        fBatch.fIndexCount += that->indexCount();
96499c7c07e0f1f7b78980eb21d84bebda8b45a7178joshualitt
96599c7c07e0f1f7b78980eb21d84bebda8b45a7178joshualitt        this->joinBounds(that->bounds());
9660823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt        return true;
9670823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt    }
9680823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt
9690823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt    struct BatchTracker {
9700823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt        GrPrimitiveType fPrimitiveType;
9710823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt        SkMatrix fViewMatrix;
9720823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt        GrColor fColor;
9730823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt        bool fUsesLocalCoords;
9740823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt        bool fColorIgnored;
9750823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt        bool fCoverageIgnored;
9760823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt        bool fHasColors;
9770823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt        bool fHasIndices;
9780823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt        bool fHasLocalCoords;
9790823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt        int fVertexCount;
9800823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt        int fIndexCount;
9810823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt    };
9820823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt
9830823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt    BatchTracker fBatch;
9840823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt    SkSTArray<1, Geometry, true> fGeoData;
9850823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt};
9860823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt
98725d9c154087d2132a51d1ca74a104726f60ef380joshualittvoid GrContext::drawVertices(GrRenderTarget* rt,
988570d2f81a65fc868d6300a7edf34c0d5d048c5d6joshualitt                             const GrClip& clip,
98925d9c154087d2132a51d1ca74a104726f60ef380joshualitt                             const GrPaint& paint,
9905531d51ce7426bdae7563547326fcf0bf926a083joshualitt                             const SkMatrix& viewMatrix,
99127847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com                             GrPrimitiveType primitiveType,
99227847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com                             int vertexCount,
993972f9cd7a063d0544f8c919fd12b9a3adbd12b24commit-bot@chromium.org                             const SkPoint positions[],
994972f9cd7a063d0544f8c919fd12b9a3adbd12b24commit-bot@chromium.org                             const SkPoint texCoords[],
99527847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com                             const GrColor colors[],
99627847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com                             const uint16_t indices[],
99727847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com                             int indexCount) {
9985f5a8d7599b8e248633ac122294b7a01401fedcbjoshualitt    RETURN_IF_ABANDONED
999f21dab95405979a4aff9f6a741c818304a67f220bsalomon    AutoCheckFlush acf(this);
10008dd688b7569df569a672a8a67b2db86a9d376cfcegdaniel    GrPipelineBuilder pipelineBuilder;
10015a56793b2a19eaf90b67d6f24441cc475d74ef17commit-bot@chromium.org
1002570d2f81a65fc868d6300a7edf34c0d5d048c5d6joshualitt    GrDrawTarget* target = this->prepareToDraw(&pipelineBuilder, rt, clip, &paint, &acf);
100341ebbddd76b747d5fb32c02dda0de3d03a3edda5bsalomon    if (NULL == target) {
100441ebbddd76b747d5fb32c02dda0de3d03a3edda5bsalomon        return;
100541ebbddd76b747d5fb32c02dda0de3d03a3edda5bsalomon    }
100627847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com
10072a05de0c049a8648942a55016126a1f92e1c14d6commit-bot@chromium.org    GR_CREATE_TRACE_MARKER("GrContext::drawVertices", target);
10082a05de0c049a8648942a55016126a1f92e1c14d6commit-bot@chromium.org
1009a09c0461463a5976908af5232b755e1663b972bfjoshualitt    // TODO clients should give us bounds
1010a09c0461463a5976908af5232b755e1663b972bfjoshualitt    SkRect bounds;
1011a09c0461463a5976908af5232b755e1663b972bfjoshualitt    if (!bounds.setBoundsCheck(positions, vertexCount)) {
1012a09c0461463a5976908af5232b755e1663b972bfjoshualitt        SkDebugf("drawVertices call empty bounds\n");
1013a09c0461463a5976908af5232b755e1663b972bfjoshualitt        return;
1014a09c0461463a5976908af5232b755e1663b972bfjoshualitt    }
1015a09c0461463a5976908af5232b755e1663b972bfjoshualitt
10160c14bccc3195e395594d5a737f14b4a6ccd8859djoshualitt    viewMatrix.mapRect(&bounds);
10170c14bccc3195e395594d5a737f14b4a6ccd8859djoshualitt
10184c977868bbe100d6d95f9e53cf176d611eceb3dcjoshualitt    // If we don't have AA then we outset for a half pixel in each direction to account for
10194c977868bbe100d6d95f9e53cf176d611eceb3dcjoshualitt    // snapping
10204c977868bbe100d6d95f9e53cf176d611eceb3dcjoshualitt    if (!paint.isAntiAlias()) {
10214c977868bbe100d6d95f9e53cf176d611eceb3dcjoshualitt        bounds.outset(0.5f, 0.5f);
10224c977868bbe100d6d95f9e53cf176d611eceb3dcjoshualitt    }
10234c977868bbe100d6d95f9e53cf176d611eceb3dcjoshualitt
10240823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt    DrawVerticesBatch::Geometry geometry;
10250823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt    geometry.fColor = paint.getColor();
10260823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt    SkAutoTUnref<GrBatch> batch(DrawVerticesBatch::Create(geometry, primitiveType, viewMatrix,
10270823bfae151dd27f364db3a7f07017a7cef6bfddjoshualitt                                                          positions, vertexCount, indices,
102899c7c07e0f1f7b78980eb21d84bebda8b45a7178joshualitt                                                          indexCount, colors, texCoords,
102999c7c07e0f1f7b78980eb21d84bebda8b45a7178joshualitt                                                          bounds));
103027847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com
103199c7c07e0f1f7b78980eb21d84bebda8b45a7178joshualitt    target->drawBatch(&pipelineBuilder, batch);
103227847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com}
103327847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com
103406afe7b5a1ef03bfc6494c51ab2a1f7a386de5c2bsalomon@google.com///////////////////////////////////////////////////////////////////////////////
103593c9660cd158c5d0cab0ba4223e4257f699d5bb8bsalomon@google.com
103625d9c154087d2132a51d1ca74a104726f60ef380joshualittvoid GrContext::drawRRect(GrRenderTarget*rt,
1037570d2f81a65fc868d6300a7edf34c0d5d048c5d6joshualitt                          const GrClip& clip,
103825d9c154087d2132a51d1ca74a104726f60ef380joshualitt                          const GrPaint& paint,
10395531d51ce7426bdae7563547326fcf0bf926a083joshualitt                          const SkMatrix& viewMatrix,
10400a09d7195b8d9945e5c9c76cc4cfe6ef65d6d390commit-bot@chromium.org                          const SkRRect& rrect,
1041d58a0ba9cff9fcefe5047e88ccb4a6e76c591c40egdaniel                          const GrStrokeInfo& strokeInfo) {
10425f5a8d7599b8e248633ac122294b7a01401fedcbjoshualitt    RETURN_IF_ABANDONED
10430a09d7195b8d9945e5c9c76cc4cfe6ef65d6d390commit-bot@chromium.org    if (rrect.isEmpty()) {
104419dd017a6256be636ccb550752bb563c4e7caeb5commit-bot@chromium.org       return;
104519dd017a6256be636ccb550752bb563c4e7caeb5commit-bot@chromium.org    }
1046f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org
1047d58a0ba9cff9fcefe5047e88ccb4a6e76c591c40egdaniel    if (strokeInfo.isDashed()) {
1048d58a0ba9cff9fcefe5047e88ccb4a6e76c591c40egdaniel        SkPath path;
1049d58a0ba9cff9fcefe5047e88ccb4a6e76c591c40egdaniel        path.addRRect(rrect);
1050570d2f81a65fc868d6300a7edf34c0d5d048c5d6joshualitt        this->drawPath(rt, clip, paint, viewMatrix, path, strokeInfo);
1051d58a0ba9cff9fcefe5047e88ccb4a6e76c591c40egdaniel        return;
1052d58a0ba9cff9fcefe5047e88ccb4a6e76c591c40egdaniel    }
1053d58a0ba9cff9fcefe5047e88ccb4a6e76c591c40egdaniel
1054f21dab95405979a4aff9f6a741c818304a67f220bsalomon    AutoCheckFlush acf(this);
10558dd688b7569df569a672a8a67b2db86a9d376cfcegdaniel    GrPipelineBuilder pipelineBuilder;
1056570d2f81a65fc868d6300a7edf34c0d5d048c5d6joshualitt    GrDrawTarget* target = this->prepareToDraw(&pipelineBuilder, rt, clip, &paint, &acf);
105741ebbddd76b747d5fb32c02dda0de3d03a3edda5bsalomon    if (NULL == target) {
105841ebbddd76b747d5fb32c02dda0de3d03a3edda5bsalomon        return;
105941ebbddd76b747d5fb32c02dda0de3d03a3edda5bsalomon    }
1060f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org
10612a05de0c049a8648942a55016126a1f92e1c14d6commit-bot@chromium.org    GR_CREATE_TRACE_MARKER("GrContext::drawRRect", target);
10622a05de0c049a8648942a55016126a1f92e1c14d6commit-bot@chromium.org
1063d58a0ba9cff9fcefe5047e88ccb4a6e76c591c40egdaniel    const SkStrokeRec& strokeRec = strokeInfo.getStrokeRec();
1064d58a0ba9cff9fcefe5047e88ccb4a6e76c591c40egdaniel
10652e3b3e369d79e78f7635d4c20e83a47ab571bdf2joshualitt    GrColor color = paint.getColor();
106644701df5ce572ac3cccec785cf52103d3d5d14a5joshualitt    if (!fOvalRenderer->drawRRect(target,
106744701df5ce572ac3cccec785cf52103d3d5d14a5joshualitt                                  &pipelineBuilder,
106844701df5ce572ac3cccec785cf52103d3d5d14a5joshualitt                                  color,
106944701df5ce572ac3cccec785cf52103d3d5d14a5joshualitt                                  viewMatrix,
107044701df5ce572ac3cccec785cf52103d3d5d14a5joshualitt                                  paint.isAntiAlias(),
107144701df5ce572ac3cccec785cf52103d3d5d14a5joshualitt                                  rrect,
107244701df5ce572ac3cccec785cf52103d3d5d14a5joshualitt                                  strokeRec)) {
1073f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org        SkPath path;
10740a09d7195b8d9945e5c9c76cc4cfe6ef65d6d390commit-bot@chromium.org        path.addRRect(rrect);
10758dd688b7569df569a672a8a67b2db86a9d376cfcegdaniel        this->internalDrawPath(target, &pipelineBuilder, viewMatrix, color, paint.isAntiAlias(),
10768dd688b7569df569a672a8a67b2db86a9d376cfcegdaniel                               path, strokeInfo);
1077f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org    }
1078f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org}
1079f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org
1080f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org///////////////////////////////////////////////////////////////////////////////
1081f2bfd54de32ffbcf90ddcd0e249aaebb1559d9c2commit-bot@chromium.org
108225d9c154087d2132a51d1ca74a104726f60ef380joshualittvoid GrContext::drawDRRect(GrRenderTarget* rt,
1083570d2f81a65fc868d6300a7edf34c0d5d048c5d6joshualitt                           const GrClip& clip,
108425d9c154087d2132a51d1ca74a104726f60ef380joshualitt                           const GrPaint& paint,
10855531d51ce7426bdae7563547326fcf0bf926a083joshualitt                           const SkMatrix& viewMatrix,
10860a09d7195b8d9945e5c9c76cc4cfe6ef65d6d390commit-bot@chromium.org                           const SkRRect& outer,
10870a09d7195b8d9945e5c9c76cc4cfe6ef65d6d390commit-bot@chromium.org                           const SkRRect& inner) {
10885f5a8d7599b8e248633ac122294b7a01401fedcbjoshualitt    RETURN_IF_ABANDONED
10890a09d7195b8d9945e5c9c76cc4cfe6ef65d6d390commit-bot@chromium.org    if (outer.isEmpty()) {
10900a09d7195b8d9945e5c9c76cc4cfe6ef65d6d390commit-bot@chromium.org       return;
10910a09d7195b8d9945e5c9c76cc4cfe6ef65d6d390commit-bot@chromium.org    }
10920a09d7195b8d9945e5c9c76cc4cfe6ef65d6d390commit-bot@chromium.org
1093f21dab95405979a4aff9f6a741c818304a67f220bsalomon    AutoCheckFlush acf(this);
10948dd688b7569df569a672a8a67b2db86a9d376cfcegdaniel    GrPipelineBuilder pipelineBuilder;
1095570d2f81a65fc868d6300a7edf34c0d5d048c5d6joshualitt    GrDrawTarget* target = this->prepareToDraw(&pipelineBuilder, rt, clip, &paint, &acf);
10960a09d7195b8d9945e5c9c76cc4cfe6ef65d6d390commit-bot@chromium.org
10970a09d7195b8d9945e5c9c76cc4cfe6ef65d6d390commit-bot@chromium.org    GR_CREATE_TRACE_MARKER("GrContext::drawDRRect", target);
10980a09d7195b8d9945e5c9c76cc4cfe6ef65d6d390commit-bot@chromium.org
10992e3b3e369d79e78f7635d4c20e83a47ab571bdf2joshualitt    GrColor color = paint.getColor();
110044701df5ce572ac3cccec785cf52103d3d5d14a5joshualitt    if (!fOvalRenderer->drawDRRect(target,
110144701df5ce572ac3cccec785cf52103d3d5d14a5joshualitt                                   &pipelineBuilder,
110244701df5ce572ac3cccec785cf52103d3d5d14a5joshualitt                                   color,
110344701df5ce572ac3cccec785cf52103d3d5d14a5joshualitt                                   viewMatrix,
110444701df5ce572ac3cccec785cf52103d3d5d14a5joshualitt                                   paint.isAntiAlias(),
110544701df5ce572ac3cccec785cf52103d3d5d14a5joshualitt                                   outer,
110644701df5ce572ac3cccec785cf52103d3d5d14a5joshualitt                                   inner)) {
11070a09d7195b8d9945e5c9c76cc4cfe6ef65d6d390commit-bot@chromium.org        SkPath path;
11080a09d7195b8d9945e5c9c76cc4cfe6ef65d6d390commit-bot@chromium.org        path.addRRect(inner);
11090a09d7195b8d9945e5c9c76cc4cfe6ef65d6d390commit-bot@chromium.org        path.addRRect(outer);
11100a09d7195b8d9945e5c9c76cc4cfe6ef65d6d390commit-bot@chromium.org        path.setFillType(SkPath::kEvenOdd_FillType);
11110a09d7195b8d9945e5c9c76cc4cfe6ef65d6d390commit-bot@chromium.org
1112d58a0ba9cff9fcefe5047e88ccb4a6e76c591c40egdaniel        GrStrokeInfo fillRec(SkStrokeRec::kFill_InitStyle);
11138dd688b7569df569a672a8a67b2db86a9d376cfcegdaniel        this->internalDrawPath(target, &pipelineBuilder, viewMatrix, color, paint.isAntiAlias(),
11148dd688b7569df569a672a8a67b2db86a9d376cfcegdaniel                               path, fillRec);
11150a09d7195b8d9945e5c9c76cc4cfe6ef65d6d390commit-bot@chromium.org    }
11160a09d7195b8d9945e5c9c76cc4cfe6ef65d6d390commit-bot@chromium.org}
11170a09d7195b8d9945e5c9c76cc4cfe6ef65d6d390commit-bot@chromium.org
11180a09d7195b8d9945e5c9c76cc4cfe6ef65d6d390commit-bot@chromium.org///////////////////////////////////////////////////////////////////////////////
11190a09d7195b8d9945e5c9c76cc4cfe6ef65d6d390commit-bot@chromium.org
1120570d2f81a65fc868d6300a7edf34c0d5d048c5d6joshualittvoid GrContext::drawOval(GrRenderTarget* rt,
1121570d2f81a65fc868d6300a7edf34c0d5d048c5d6joshualitt                         const GrClip& clip,
112225d9c154087d2132a51d1ca74a104726f60ef380joshualitt                         const GrPaint& paint,
11235531d51ce7426bdae7563547326fcf0bf926a083joshualitt                         const SkMatrix& viewMatrix,
1124fd03d4a829efe2d77a712fd991927c55f59a2ffecommit-bot@chromium.org                         const SkRect& oval,
1125d58a0ba9cff9fcefe5047e88ccb4a6e76c591c40egdaniel                         const GrStrokeInfo& strokeInfo) {
11265f5a8d7599b8e248633ac122294b7a01401fedcbjoshualitt    RETURN_IF_ABANDONED
112719dd017a6256be636ccb550752bb563c4e7caeb5commit-bot@chromium.org    if (oval.isEmpty()) {
112819dd017a6256be636ccb550752bb563c4e7caeb5commit-bot@chromium.org       return;
112919dd017a6256be636ccb550752bb563c4e7caeb5commit-bot@chromium.org    }
113093c9660cd158c5d0cab0ba4223e4257f699d5bb8bsalomon@google.com
1131d58a0ba9cff9fcefe5047e88ccb4a6e76c591c40egdaniel    if (strokeInfo.isDashed()) {
1132d58a0ba9cff9fcefe5047e88ccb4a6e76c591c40egdaniel        SkPath path;
1133d58a0ba9cff9fcefe5047e88ccb4a6e76c591c40egdaniel        path.addOval(oval);
1134570d2f81a65fc868d6300a7edf34c0d5d048c5d6joshualitt        this->drawPath(rt, clip, paint, viewMatrix, path, strokeInfo);
1135d58a0ba9cff9fcefe5047e88ccb4a6e76c591c40egdaniel        return;
1136d58a0ba9cff9fcefe5047e88ccb4a6e76c591c40egdaniel    }
1137d58a0ba9cff9fcefe5047e88ccb4a6e76c591c40egdaniel
1138f21dab95405979a4aff9f6a741c818304a67f220bsalomon    AutoCheckFlush acf(this);
11398dd688b7569df569a672a8a67b2db86a9d376cfcegdaniel    GrPipelineBuilder pipelineBuilder;
1140570d2f81a65fc868d6300a7edf34c0d5d048c5d6joshualitt    GrDrawTarget* target = this->prepareToDraw(&pipelineBuilder, rt, clip, &paint, &acf);
114141ebbddd76b747d5fb32c02dda0de3d03a3edda5bsalomon    if (NULL == target) {
114241ebbddd76b747d5fb32c02dda0de3d03a3edda5bsalomon        return;
114341ebbddd76b747d5fb32c02dda0de3d03a3edda5bsalomon    }
11440982d35187da7e1ed6c0eba5951bbdadca8b33e7bsalomon@google.com
11452a05de0c049a8648942a55016126a1f92e1c14d6commit-bot@chromium.org    GR_CREATE_TRACE_MARKER("GrContext::drawOval", target);
11462a05de0c049a8648942a55016126a1f92e1c14d6commit-bot@chromium.org
1147d58a0ba9cff9fcefe5047e88ccb4a6e76c591c40egdaniel    const SkStrokeRec& strokeRec = strokeInfo.getStrokeRec();
1148d58a0ba9cff9fcefe5047e88ccb4a6e76c591c40egdaniel
11492e3b3e369d79e78f7635d4c20e83a47ab571bdf2joshualitt    GrColor color = paint.getColor();
115044701df5ce572ac3cccec785cf52103d3d5d14a5joshualitt    if (!fOvalRenderer->drawOval(target,
115144701df5ce572ac3cccec785cf52103d3d5d14a5joshualitt                                 &pipelineBuilder,
115244701df5ce572ac3cccec785cf52103d3d5d14a5joshualitt                                 color,
115344701df5ce572ac3cccec785cf52103d3d5d14a5joshualitt                                 viewMatrix,
115444701df5ce572ac3cccec785cf52103d3d5d14a5joshualitt                                 paint.isAntiAlias(),
115544701df5ce572ac3cccec785cf52103d3d5d14a5joshualitt                                 oval,
115644701df5ce572ac3cccec785cf52103d3d5d14a5joshualitt                                 strokeRec)) {
115781312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org        SkPath path;
115881312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org        path.addOval(oval);
11598dd688b7569df569a672a8a67b2db86a9d376cfcegdaniel        this->internalDrawPath(target, &pipelineBuilder, viewMatrix, color, paint.isAntiAlias(),
11608dd688b7569df569a672a8a67b2db86a9d376cfcegdaniel                               path, strokeInfo);
116146d3d39e65e0b3ea2ad7c91c176ccafb4df0fa24jvanverth@google.com    }
1162150d28465d340e3c6da6a3e1fd5adfdb128e61d0bsalomon@google.com}
116327847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com
116483d1a68141830cbfa0d5fca6f9c9bccf9c978ad2robertphillips@google.com// Can 'path' be drawn as a pair of filled nested rectangles?
116583d1a68141830cbfa0d5fca6f9c9bccf9c978ad2robertphillips@google.comstatic bool is_nested_rects(GrDrawTarget* target,
11668dd688b7569df569a672a8a67b2db86a9d376cfcegdaniel                            GrPipelineBuilder* pipelineBuilder,
11672e3b3e369d79e78f7635d4c20e83a47ab571bdf2joshualitt                            GrColor color,
11688059eb9f6e24ed609393fbda4ad71edea03ac258joshualitt                            const SkMatrix& viewMatrix,
116983d1a68141830cbfa0d5fca6f9c9bccf9c978ad2robertphillips@google.com                            const SkPath& path,
117083d1a68141830cbfa0d5fca6f9c9bccf9c978ad2robertphillips@google.com                            const SkStrokeRec& stroke,
11719c0822a4150e23cec9f9b72bd1abc2c5f9ea5a3bbsalomon                            SkRect rects[2]) {
117283d1a68141830cbfa0d5fca6f9c9bccf9c978ad2robertphillips@google.com    SkASSERT(stroke.isFillStyle());
117383d1a68141830cbfa0d5fca6f9c9bccf9c978ad2robertphillips@google.com
117483d1a68141830cbfa0d5fca6f9c9bccf9c978ad2robertphillips@google.com    if (path.isInverseFillType()) {
117583d1a68141830cbfa0d5fca6f9c9bccf9c978ad2robertphillips@google.com        return false;
117683d1a68141830cbfa0d5fca6f9c9bccf9c978ad2robertphillips@google.com    }
117783d1a68141830cbfa0d5fca6f9c9bccf9c978ad2robertphillips@google.com
117883d1a68141830cbfa0d5fca6f9c9bccf9c978ad2robertphillips@google.com    // TODO: this restriction could be lifted if we were willing to apply
117983d1a68141830cbfa0d5fca6f9c9bccf9c978ad2robertphillips@google.com    // the matrix to all the points individually rather than just to the rect
11808059eb9f6e24ed609393fbda4ad71edea03ac258joshualitt    if (!viewMatrix.preservesAxisAlignment()) {
118183d1a68141830cbfa0d5fca6f9c9bccf9c978ad2robertphillips@google.com        return false;
118283d1a68141830cbfa0d5fca6f9c9bccf9c978ad2robertphillips@google.com    }
118383d1a68141830cbfa0d5fca6f9c9bccf9c978ad2robertphillips@google.com
118483d1a68141830cbfa0d5fca6f9c9bccf9c978ad2robertphillips@google.com    SkPath::Direction dirs[2];
118595bc5f349561fef2d6fbae71adb08cf5c2eec0c9caryclark    if (!path.isNestedFillRects(rects, dirs)) {
118683d1a68141830cbfa0d5fca6f9c9bccf9c978ad2robertphillips@google.com        return false;
118783d1a68141830cbfa0d5fca6f9c9bccf9c978ad2robertphillips@google.com    }
118883d1a68141830cbfa0d5fca6f9c9bccf9c978ad2robertphillips@google.com
11898d3c640b5aa96d6316a3e52975602b35e1a66ac7robertphillips@google.com    if (SkPath::kWinding_FillType == path.getFillType() && dirs[0] == dirs[1]) {
119083d1a68141830cbfa0d5fca6f9c9bccf9c978ad2robertphillips@google.com        // The two rects need to be wound opposite to each other
11918d3c640b5aa96d6316a3e52975602b35e1a66ac7robertphillips@google.com        return false;
119283d1a68141830cbfa0d5fca6f9c9bccf9c978ad2robertphillips@google.com    }
119383d1a68141830cbfa0d5fca6f9c9bccf9c978ad2robertphillips@google.com
11948d3c640b5aa96d6316a3e52975602b35e1a66ac7robertphillips@google.com    // Right now, nested rects where the margin is not the same width
11958d3c640b5aa96d6316a3e52975602b35e1a66ac7robertphillips@google.com    // all around do not render correctly
11968d3c640b5aa96d6316a3e52975602b35e1a66ac7robertphillips@google.com    const SkScalar* outer = rects[0].asScalars();
11978d3c640b5aa96d6316a3e52975602b35e1a66ac7robertphillips@google.com    const SkScalar* inner = rects[1].asScalars();
11988d3c640b5aa96d6316a3e52975602b35e1a66ac7robertphillips@google.com
1199183e98559c2edf6b262fa6c6fff7f3013eb42f5arobertphillips    bool allEq = true;
1200183e98559c2edf6b262fa6c6fff7f3013eb42f5arobertphillips
12018d3c640b5aa96d6316a3e52975602b35e1a66ac7robertphillips@google.com    SkScalar margin = SkScalarAbs(outer[0] - inner[0]);
1202183e98559c2edf6b262fa6c6fff7f3013eb42f5arobertphillips    bool allGoE1 = margin >= SK_Scalar1;
1203183e98559c2edf6b262fa6c6fff7f3013eb42f5arobertphillips
12048d3c640b5aa96d6316a3e52975602b35e1a66ac7robertphillips@google.com    for (int i = 1; i < 4; ++i) {
12058d3c640b5aa96d6316a3e52975602b35e1a66ac7robertphillips@google.com        SkScalar temp = SkScalarAbs(outer[i] - inner[i]);
1206183e98559c2edf6b262fa6c6fff7f3013eb42f5arobertphillips        if (temp < SK_Scalar1) {
1207183e98559c2edf6b262fa6c6fff7f3013eb42f5arobertphillips            allGoE1 = false;
1208183e98559c2edf6b262fa6c6fff7f3013eb42f5arobertphillips        }
12098d3c640b5aa96d6316a3e52975602b35e1a66ac7robertphillips@google.com        if (!SkScalarNearlyEqual(margin, temp)) {
1210183e98559c2edf6b262fa6c6fff7f3013eb42f5arobertphillips            allEq = false;
12118d3c640b5aa96d6316a3e52975602b35e1a66ac7robertphillips@google.com        }
12128d3c640b5aa96d6316a3e52975602b35e1a66ac7robertphillips@google.com    }
12138d3c640b5aa96d6316a3e52975602b35e1a66ac7robertphillips@google.com
1214183e98559c2edf6b262fa6c6fff7f3013eb42f5arobertphillips    return allEq || allGoE1;
12158d3c640b5aa96d6316a3e52975602b35e1a66ac7robertphillips@google.com}
121683d1a68141830cbfa0d5fca6f9c9bccf9c978ad2robertphillips@google.com
121725d9c154087d2132a51d1ca74a104726f60ef380joshualittvoid GrContext::drawPath(GrRenderTarget* rt,
1218570d2f81a65fc868d6300a7edf34c0d5d048c5d6joshualitt                         const GrClip& clip,
121925d9c154087d2132a51d1ca74a104726f60ef380joshualitt                         const GrPaint& paint,
12205531d51ce7426bdae7563547326fcf0bf926a083joshualitt                         const SkMatrix& viewMatrix,
12215531d51ce7426bdae7563547326fcf0bf926a083joshualitt                         const SkPath& path,
12225531d51ce7426bdae7563547326fcf0bf926a083joshualitt                         const GrStrokeInfo& strokeInfo) {
12235f5a8d7599b8e248633ac122294b7a01401fedcbjoshualitt    RETURN_IF_ABANDONED
1224fa6ac938e64fe11b442d05fe8a90ddac2d1951f9bsalomon@google.com    if (path.isEmpty()) {
122512b4e27ae1a29460e91a59f38122483e1faec697sugoi@google.com       if (path.isInverseFillType()) {
1226570d2f81a65fc868d6300a7edf34c0d5d048c5d6joshualitt           this->drawPaint(rt, clip, paint, viewMatrix);
1227fa6ac938e64fe11b442d05fe8a90ddac2d1951f9bsalomon@google.com       }
1228fa6ac938e64fe11b442d05fe8a90ddac2d1951f9bsalomon@google.com       return;
1229fa6ac938e64fe11b442d05fe8a90ddac2d1951f9bsalomon@google.com    }
1230fa6ac938e64fe11b442d05fe8a90ddac2d1951f9bsalomon@google.com
12312e3b3e369d79e78f7635d4c20e83a47ab571bdf2joshualitt    GrColor color = paint.getColor();
1232d58a0ba9cff9fcefe5047e88ccb4a6e76c591c40egdaniel
123381312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org    // Note that internalDrawPath may sw-rasterize the path into a scratch texture.
123481312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org    // Scratch textures can be recycled after they are returned to the texture
123581312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org    // cache. This presents a potential hazard for buffered drawing. However,
123681312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org    // the writePixels that uploads to the scratch will perform a flush so we're
123781312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org    // OK.
1238f21dab95405979a4aff9f6a741c818304a67f220bsalomon    AutoCheckFlush acf(this);
12398dd688b7569df569a672a8a67b2db86a9d376cfcegdaniel    GrPipelineBuilder pipelineBuilder;
1240570d2f81a65fc868d6300a7edf34c0d5d048c5d6joshualitt    GrDrawTarget* target = this->prepareToDraw(&pipelineBuilder, rt, clip, &paint, &acf);
124141ebbddd76b747d5fb32c02dda0de3d03a3edda5bsalomon    if (NULL == target) {
124241ebbddd76b747d5fb32c02dda0de3d03a3edda5bsalomon        return;
124341ebbddd76b747d5fb32c02dda0de3d03a3edda5bsalomon    }
124481312830ef73420efdc4821feb7c2d6fd9152af8commit-bot@chromium.org
124593a37bc91a40a7cd14f9f8eca6097535ab1099e4egdaniel    GR_CREATE_TRACE_MARKER1("GrContext::drawPath", target, "Is Convex", path.isConvex());
12462a05de0c049a8648942a55016126a1f92e1c14d6commit-bot@chromium.org
12471899651ffc459f5462aa989cd6d08507947b67e4kkinnunen    if (!strokeInfo.isDashed()) {
12481899651ffc459f5462aa989cd6d08507947b67e4kkinnunen        const SkStrokeRec& strokeRec = strokeInfo.getStrokeRec();
12491899651ffc459f5462aa989cd6d08507947b67e4kkinnunen        bool useCoverageAA = paint.isAntiAlias() &&
12501899651ffc459f5462aa989cd6d08507947b67e4kkinnunen                !pipelineBuilder.getRenderTarget()->isMultisampled();
1251e0a868c84ebc34c5a16b5faa1546016abb9ca0accommit-bot@chromium.org
12521899651ffc459f5462aa989cd6d08507947b67e4kkinnunen        if (useCoverageAA && strokeRec.getWidth() < 0 && !path.isConvex()) {
12531899651ffc459f5462aa989cd6d08507947b67e4kkinnunen            // Concave AA paths are expensive - try to avoid them for special cases
12541899651ffc459f5462aa989cd6d08507947b67e4kkinnunen            SkRect rects[2];
125583d1a68141830cbfa0d5fca6f9c9bccf9c978ad2robertphillips@google.com
12561899651ffc459f5462aa989cd6d08507947b67e4kkinnunen            if (is_nested_rects(target, &pipelineBuilder, color, viewMatrix, path, strokeRec,
12571899651ffc459f5462aa989cd6d08507947b67e4kkinnunen                                rects)) {
12581899651ffc459f5462aa989cd6d08507947b67e4kkinnunen                fAARectRenderer->fillAANestedRects(target, &pipelineBuilder, color, viewMatrix,
12591899651ffc459f5462aa989cd6d08507947b67e4kkinnunen                                                   rects);
12601899651ffc459f5462aa989cd6d08507947b67e4kkinnunen                return;
12611899651ffc459f5462aa989cd6d08507947b67e4kkinnunen            }
126283d1a68141830cbfa0d5fca6f9c9bccf9c978ad2robertphillips@google.com        }
12631899651ffc459f5462aa989cd6d08507947b67e4kkinnunen        SkRect ovalRect;
12641899651ffc459f5462aa989cd6d08507947b67e4kkinnunen        bool isOval = path.isOval(&ovalRect);
126583d1a68141830cbfa0d5fca6f9c9bccf9c978ad2robertphillips@google.com
12661899651ffc459f5462aa989cd6d08507947b67e4kkinnunen        if (isOval && !path.isInverseFillType()) {
12671899651ffc459f5462aa989cd6d08507947b67e4kkinnunen            if (fOvalRenderer->drawOval(target,
12681899651ffc459f5462aa989cd6d08507947b67e4kkinnunen                                        &pipelineBuilder,
12691899651ffc459f5462aa989cd6d08507947b67e4kkinnunen                                        color,
12701899651ffc459f5462aa989cd6d08507947b67e4kkinnunen                                        viewMatrix,
12711899651ffc459f5462aa989cd6d08507947b67e4kkinnunen                                        paint.isAntiAlias(),
12721899651ffc459f5462aa989cd6d08507947b67e4kkinnunen                                        ovalRect,
12731899651ffc459f5462aa989cd6d08507947b67e4kkinnunen                                        strokeRec)) {
12741899651ffc459f5462aa989cd6d08507947b67e4kkinnunen                return;
12751899651ffc459f5462aa989cd6d08507947b67e4kkinnunen            }
12761899651ffc459f5462aa989cd6d08507947b67e4kkinnunen        }
127793c9660cd158c5d0cab0ba4223e4257f699d5bb8bsalomon@google.com    }
12781899651ffc459f5462aa989cd6d08507947b67e4kkinnunen    this->internalDrawPath(target, &pipelineBuilder, viewMatrix, color, paint.isAntiAlias(),
12791899651ffc459f5462aa989cd6d08507947b67e4kkinnunen                           path, strokeInfo);
128093c9660cd158c5d0cab0ba4223e4257f699d5bb8bsalomon@google.com}
128193c9660cd158c5d0cab0ba4223e4257f699d5bb8bsalomon@google.com
12829853ccef19c200be93a6211f32589fa82a53067cjoshualittvoid GrContext::internalDrawPath(GrDrawTarget* target,
12838dd688b7569df569a672a8a67b2db86a9d376cfcegdaniel                                 GrPipelineBuilder* pipelineBuilder,
12845531d51ce7426bdae7563547326fcf0bf926a083joshualitt                                 const SkMatrix& viewMatrix,
12852e3b3e369d79e78f7635d4c20e83a47ab571bdf2joshualitt                                 GrColor color,
12869853ccef19c200be93a6211f32589fa82a53067cjoshualitt                                 bool useAA,
12879853ccef19c200be93a6211f32589fa82a53067cjoshualitt                                 const SkPath& path,
1288d58a0ba9cff9fcefe5047e88ccb4a6e76c591c40egdaniel                                 const GrStrokeInfo& strokeInfo) {
12895f5a8d7599b8e248633ac122294b7a01401fedcbjoshualitt    RETURN_IF_ABANDONED
129019dd017a6256be636ccb550752bb563c4e7caeb5commit-bot@chromium.org    SkASSERT(!path.isEmpty());
129193c9660cd158c5d0cab0ba4223e4257f699d5bb8bsalomon@google.com
12922a05de0c049a8648942a55016126a1f92e1c14d6commit-bot@chromium.org    GR_CREATE_TRACE_MARKER("GrContext::internalDrawPath", target);
12932a05de0c049a8648942a55016126a1f92e1c14d6commit-bot@chromium.org
12942a05de0c049a8648942a55016126a1f92e1c14d6commit-bot@chromium.org
1295d46e2423a71d38b8a057cec2356741e35b03334dbsalomon@google.com    // An Assumption here is that path renderer would use some form of tweaking
1296d46e2423a71d38b8a057cec2356741e35b03334dbsalomon@google.com    // the src color (either the input alpha or in the frag shader) to implement
1297d46e2423a71d38b8a057cec2356741e35b03334dbsalomon@google.com    // aa. If we have some future driver-mojo path AA that can do the right
1298d46e2423a71d38b8a057cec2356741e35b03334dbsalomon@google.com    // thing WRT to the blend then we'll need some query on the PR.
1299e0a868c84ebc34c5a16b5faa1546016abb9ca0accommit-bot@chromium.org    bool useCoverageAA = useAA &&
13000bdeec9640640922eb6b0a9f798bcd85eb898f29egdaniel        !pipelineBuilder->getRenderTarget()->isMultisampled();
1301e0a868c84ebc34c5a16b5faa1546016abb9ca0accommit-bot@chromium.org
1302289533ada623f2238a83771eec977f204f75994fbsalomon@google.com
1303e0a868c84ebc34c5a16b5faa1546016abb9ca0accommit-bot@chromium.org    GrPathRendererChain::DrawType type =
1304e0a868c84ebc34c5a16b5faa1546016abb9ca0accommit-bot@chromium.org        useCoverageAA ? GrPathRendererChain::kColorAntiAlias_DrawType :
13059853ccef19c200be93a6211f32589fa82a53067cjoshualitt                        GrPathRendererChain::kColor_DrawType;
130645a15f551b5b3c6c747d8eaf6466b7d3b76a8faebsalomon@google.com
1307eb928ea49a1c8a72ba3e01f64452b20713232059robertphillips@google.com    const SkPath* pathPtr = &path;
1308f0c41e24d5322022c7678b60837274c1340fc109commit-bot@chromium.org    SkTLazy<SkPath> tmpPath;
13091899651ffc459f5462aa989cd6d08507947b67e4kkinnunen    const GrStrokeInfo* strokeInfoPtr = &strokeInfo;
1310eb928ea49a1c8a72ba3e01f64452b20713232059robertphillips@google.com
1311eb928ea49a1c8a72ba3e01f64452b20713232059robertphillips@google.com    // Try a 1st time without stroking the path and without allowing the SW renderer
13128dd688b7569df569a672a8a67b2db86a9d376cfcegdaniel    GrPathRenderer* pr = this->getPathRenderer(target, pipelineBuilder, viewMatrix, *pathPtr,
13131899651ffc459f5462aa989cd6d08507947b67e4kkinnunen                                               *strokeInfoPtr, false, type);
13141899651ffc459f5462aa989cd6d08507947b67e4kkinnunen
13151899651ffc459f5462aa989cd6d08507947b67e4kkinnunen    GrStrokeInfo dashlessStrokeInfo(strokeInfo, false);
13161899651ffc459f5462aa989cd6d08507947b67e4kkinnunen    if (NULL == pr && strokeInfo.isDashed()) {
13171899651ffc459f5462aa989cd6d08507947b67e4kkinnunen        // It didn't work above, so try again with dashed stroke converted to a dashless stroke.
131807ab9f3beda017d06089797de8c79d833b5a7659bsalomon        if (!strokeInfo.applyDash(tmpPath.init(), &dashlessStrokeInfo, *pathPtr)) {
131907ab9f3beda017d06089797de8c79d833b5a7659bsalomon            return;
132007ab9f3beda017d06089797de8c79d833b5a7659bsalomon        }
132107ab9f3beda017d06089797de8c79d833b5a7659bsalomon        pathPtr = tmpPath.get();
132207ab9f3beda017d06089797de8c79d833b5a7659bsalomon        if (pathPtr->isEmpty()) {
132307ab9f3beda017d06089797de8c79d833b5a7659bsalomon            return;
13241899651ffc459f5462aa989cd6d08507947b67e4kkinnunen        }
132507ab9f3beda017d06089797de8c79d833b5a7659bsalomon        strokeInfoPtr = &dashlessStrokeInfo;
13261899651ffc459f5462aa989cd6d08507947b67e4kkinnunen        pr = this->getPathRenderer(target, pipelineBuilder, viewMatrix, *pathPtr, *strokeInfoPtr,
13271899651ffc459f5462aa989cd6d08507947b67e4kkinnunen                                   false, type);
13281899651ffc459f5462aa989cd6d08507947b67e4kkinnunen    }
1329eb928ea49a1c8a72ba3e01f64452b20713232059robertphillips@google.com
1330e79f320ed6c5ec9f6164ba84be1ff586532e6517robertphillips@google.com    if (NULL == pr) {
133107ab9f3beda017d06089797de8c79d833b5a7659bsalomon        if (!GrPathRenderer::IsStrokeHairlineOrEquivalent(*strokeInfoPtr, viewMatrix, NULL) &&
133207ab9f3beda017d06089797de8c79d833b5a7659bsalomon            !strokeInfoPtr->isFillStyle()) {
13331899651ffc459f5462aa989cd6d08507947b67e4kkinnunen            // It didn't work above, so try again with stroke converted to a fill.
13341899651ffc459f5462aa989cd6d08507947b67e4kkinnunen            if (!tmpPath.isValid()) {
13351899651ffc459f5462aa989cd6d08507947b67e4kkinnunen                tmpPath.init();
13361899651ffc459f5462aa989cd6d08507947b67e4kkinnunen            }
13371899651ffc459f5462aa989cd6d08507947b67e4kkinnunen            SkStrokeRec* strokeRec = dashlessStrokeInfo.getStrokeRecPtr();
13381899651ffc459f5462aa989cd6d08507947b67e4kkinnunen            strokeRec->setResScale(SkScalarAbs(viewMatrix.getMaxScale()));
133907ab9f3beda017d06089797de8c79d833b5a7659bsalomon            if (!strokeRec->applyToPath(tmpPath.get(), *pathPtr)) {
134007ab9f3beda017d06089797de8c79d833b5a7659bsalomon                return;
134107ab9f3beda017d06089797de8c79d833b5a7659bsalomon            }
134207ab9f3beda017d06089797de8c79d833b5a7659bsalomon            pathPtr = tmpPath.get();
134307ab9f3beda017d06089797de8c79d833b5a7659bsalomon            if (pathPtr->isEmpty()) {
134407ab9f3beda017d06089797de8c79d833b5a7659bsalomon                return;
1345eb928ea49a1c8a72ba3e01f64452b20713232059robertphillips@google.com            }
134607ab9f3beda017d06089797de8c79d833b5a7659bsalomon            strokeRec->setFillStyle();
134707ab9f3beda017d06089797de8c79d833b5a7659bsalomon            strokeInfoPtr = &dashlessStrokeInfo;
1348eb928ea49a1c8a72ba3e01f64452b20713232059robertphillips@google.com        }
134919dd017a6256be636ccb550752bb563c4e7caeb5commit-bot@chromium.org
1350eb928ea49a1c8a72ba3e01f64452b20713232059robertphillips@google.com        // This time, allow SW renderer
13511899651ffc459f5462aa989cd6d08507947b67e4kkinnunen        pr = this->getPathRenderer(target, pipelineBuilder, viewMatrix, *pathPtr, *strokeInfoPtr,
13521899651ffc459f5462aa989cd6d08507947b67e4kkinnunen                                   true, type);
1353eb928ea49a1c8a72ba3e01f64452b20713232059robertphillips@google.com    }
1354eb928ea49a1c8a72ba3e01f64452b20713232059robertphillips@google.com
1355e79f320ed6c5ec9f6164ba84be1ff586532e6517robertphillips@google.com    if (NULL == pr) {
1356515dcd36032997ce335daa0163c6d67e851bcad1commit-bot@chromium.org#ifdef SK_DEBUG
135738406c82b913350e55fa04af8c1941cd9b4aff52tfarina        SkDebugf("Unable to find path renderer compatible with path.\n");
13581983f39f1bf6295c96c0f1f7ead9f568923390bcbsalomon@google.com#endif
13593008519e9f977cd60194841d558a4f45c28e9833bsalomon@google.com        return;
13603008519e9f977cd60194841d558a4f45c28e9833bsalomon@google.com    }
13613008519e9f977cd60194841d558a4f45c28e9833bsalomon@google.com
13621899651ffc459f5462aa989cd6d08507947b67e4kkinnunen    pr->drawPath(target, pipelineBuilder, color, viewMatrix, *pathPtr, *strokeInfoPtr, useCoverageAA);
136327847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com}
13648295dc1474db279df08d816b2115e807c681fad5bsalomon@google.com
136527847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com////////////////////////////////////////////////////////////////////////////////
136627847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com
1367a7f84e150cb9e821267a8ca9e59c1ae9a3cfa300bsalomon@google.comvoid GrContext::flush(int flagsBitfield) {
1368e7db8d6c0291371ae2766fd0b6fc0918a0ed1c03robertphillips@google.com    if (NULL == fDrawBuffer) {
1369e7db8d6c0291371ae2766fd0b6fc0918a0ed1c03robertphillips@google.com        return;
1370e7db8d6c0291371ae2766fd0b6fc0918a0ed1c03robertphillips@google.com    }
1371e7db8d6c0291371ae2766fd0b6fc0918a0ed1c03robertphillips@google.com
1372a7f84e150cb9e821267a8ca9e59c1ae9a3cfa300bsalomon@google.com    if (kDiscard_FlushBit & flagsBitfield) {
1373a7f84e150cb9e821267a8ca9e59c1ae9a3cfa300bsalomon@google.com        fDrawBuffer->reset();
1374a7f84e150cb9e821267a8ca9e59c1ae9a3cfa300bsalomon@google.com    } else {
13756e4e65066a7c0dbc9bfbfe4b8f5d49c3d8a79b59bsalomon@google.com        fDrawBuffer->flush();
137653a5584bb0094e19c39a66cec7f346aad04ecac4junov@google.com    }
13773f324321cdd8fde7976d958e2888a1ec4e657e35bsalomon    fResourceCache->notifyFlushOccurred();
1378f21dab95405979a4aff9f6a741c818304a67f220bsalomon    fFlushToReduceCacheSize = false;
137927847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com}
138027847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com
138181beccc4fb1396fe94af15bfce26e68b82b93809bsalomonbool sw_convert_to_premul(GrPixelConfig srcConfig, int width, int height, size_t inRowBytes,
138281beccc4fb1396fe94af15bfce26e68b82b93809bsalomon                          const void* inPixels, size_t outRowBytes, void* outPixels) {
138381beccc4fb1396fe94af15bfce26e68b82b93809bsalomon    SkSrcPixelInfo srcPI;
1384fa1e8a7cefd71f7b75f0b85f8eefe111814dd86fjvanverth    if (!GrPixelConfig2ColorAndProfileType(srcConfig, &srcPI.fColorType, NULL)) {
138581beccc4fb1396fe94af15bfce26e68b82b93809bsalomon        return false;
138681beccc4fb1396fe94af15bfce26e68b82b93809bsalomon    }
138781beccc4fb1396fe94af15bfce26e68b82b93809bsalomon    srcPI.fAlphaType = kUnpremul_SkAlphaType;
138881beccc4fb1396fe94af15bfce26e68b82b93809bsalomon    srcPI.fPixels = inPixels;
138981beccc4fb1396fe94af15bfce26e68b82b93809bsalomon    srcPI.fRowBytes = inRowBytes;
139081beccc4fb1396fe94af15bfce26e68b82b93809bsalomon
139181beccc4fb1396fe94af15bfce26e68b82b93809bsalomon    SkDstPixelInfo dstPI;
139281beccc4fb1396fe94af15bfce26e68b82b93809bsalomon    dstPI.fColorType = srcPI.fColorType;
139381beccc4fb1396fe94af15bfce26e68b82b93809bsalomon    dstPI.fAlphaType = kPremul_SkAlphaType;
139481beccc4fb1396fe94af15bfce26e68b82b93809bsalomon    dstPI.fPixels = outPixels;
139581beccc4fb1396fe94af15bfce26e68b82b93809bsalomon    dstPI.fRowBytes = outRowBytes;
139681beccc4fb1396fe94af15bfce26e68b82b93809bsalomon
139781beccc4fb1396fe94af15bfce26e68b82b93809bsalomon    return srcPI.convertPixelsTo(&dstPI, width, height);
139881beccc4fb1396fe94af15bfce26e68b82b93809bsalomon}
139981beccc4fb1396fe94af15bfce26e68b82b93809bsalomon
140081beccc4fb1396fe94af15bfce26e68b82b93809bsalomonbool GrContext::writeSurfacePixels(GrSurface* surface,
14010342a85091fd430c90a142d155dc9642aa729d9ebsalomon@google.com                                   int left, int top, int width, int height,
140281beccc4fb1396fe94af15bfce26e68b82b93809bsalomon                                   GrPixelConfig srcConfig, const void* buffer, size_t rowBytes,
140381beccc4fb1396fe94af15bfce26e68b82b93809bsalomon                                   uint32_t pixelOpsFlags) {
14045f5a8d7599b8e248633ac122294b7a01401fedcbjoshualitt    RETURN_FALSE_IF_ABANDONED
140581beccc4fb1396fe94af15bfce26e68b82b93809bsalomon    {
140681beccc4fb1396fe94af15bfce26e68b82b93809bsalomon        GrTexture* texture = NULL;
140781beccc4fb1396fe94af15bfce26e68b82b93809bsalomon        if (!(kUnpremul_PixelOpsFlag & pixelOpsFlags) && (texture = surface->asTexture()) &&
140881beccc4fb1396fe94af15bfce26e68b82b93809bsalomon            fGpu->canWriteTexturePixels(texture, srcConfig)) {
140981beccc4fb1396fe94af15bfce26e68b82b93809bsalomon
141081beccc4fb1396fe94af15bfce26e68b82b93809bsalomon            if (!(kDontFlush_PixelOpsFlag & pixelOpsFlags) &&
141181beccc4fb1396fe94af15bfce26e68b82b93809bsalomon                surface->surfacePriv().hasPendingIO()) {
141281beccc4fb1396fe94af15bfce26e68b82b93809bsalomon                this->flush();
141381beccc4fb1396fe94af15bfce26e68b82b93809bsalomon            }
141481beccc4fb1396fe94af15bfce26e68b82b93809bsalomon            return fGpu->writeTexturePixels(texture, left, top, width, height,
141581beccc4fb1396fe94af15bfce26e68b82b93809bsalomon                                            srcConfig, buffer, rowBytes);
141681beccc4fb1396fe94af15bfce26e68b82b93809bsalomon            // Don't need to check kFlushWrites_PixelOp here, we just did a direct write so the
141781beccc4fb1396fe94af15bfce26e68b82b93809bsalomon            // upload is already flushed.
14189c68058b679aee81e6e0158e7fcbfb5d8479c91absalomon@google.com        }
14196f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com    }
14209c68058b679aee81e6e0158e7fcbfb5d8479c91absalomon@google.com
142181beccc4fb1396fe94af15bfce26e68b82b93809bsalomon    // If we didn't do a direct texture write then we upload the pixels to a texture and draw.
142281beccc4fb1396fe94af15bfce26e68b82b93809bsalomon    GrRenderTarget* renderTarget = surface->asRenderTarget();
142381beccc4fb1396fe94af15bfce26e68b82b93809bsalomon    if (NULL == renderTarget) {
142481beccc4fb1396fe94af15bfce26e68b82b93809bsalomon        return false;
14250342a85091fd430c90a142d155dc9642aa729d9ebsalomon@google.com    }
14266f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com
142781beccc4fb1396fe94af15bfce26e68b82b93809bsalomon    // We ignore the preferred config unless it is a R/B swap of the src config. In that case
142881beccc4fb1396fe94af15bfce26e68b82b93809bsalomon    // we will upload the original src data to a scratch texture but we will spoof it as the swapped
142981beccc4fb1396fe94af15bfce26e68b82b93809bsalomon    // config. This scratch will then have R and B swapped. We correct for this by swapping again
143081beccc4fb1396fe94af15bfce26e68b82b93809bsalomon    // when drawing the scratch to the dst using a conversion effect.
143181beccc4fb1396fe94af15bfce26e68b82b93809bsalomon    bool swapRAndB = false;
143281beccc4fb1396fe94af15bfce26e68b82b93809bsalomon    GrPixelConfig writeConfig = srcConfig;
143381beccc4fb1396fe94af15bfce26e68b82b93809bsalomon    if (GrPixelConfigSwapRAndB(srcConfig) ==
143481beccc4fb1396fe94af15bfce26e68b82b93809bsalomon        fGpu->preferredWritePixelsConfig(srcConfig, renderTarget->config())) {
143581beccc4fb1396fe94af15bfce26e68b82b93809bsalomon        writeConfig = GrPixelConfigSwapRAndB(srcConfig);
143681beccc4fb1396fe94af15bfce26e68b82b93809bsalomon        swapRAndB = true;
143781beccc4fb1396fe94af15bfce26e68b82b93809bsalomon    }
1438f80bfedc42fde88ae3f8dbd7b21950a22258fd22bsalomon
1439f2703d83da3ab2ae18b45231fd4f11e16cce3184bsalomon    GrSurfaceDesc desc;
144081beccc4fb1396fe94af15bfce26e68b82b93809bsalomon    desc.fWidth = width;
144181beccc4fb1396fe94af15bfce26e68b82b93809bsalomon    desc.fHeight = height;
144281beccc4fb1396fe94af15bfce26e68b82b93809bsalomon    desc.fConfig = writeConfig;
1443d309e7aa0efa2d5dd7e7b1af97026fcd3a047e98bsalomon    SkAutoTUnref<GrTexture> texture(this->textureProvider()->refScratchTexture(desc,
1444d309e7aa0efa2d5dd7e7b1af97026fcd3a047e98bsalomon        GrTextureProvider::kApprox_ScratchTexMatch));
1445e30597375c19dfb5197fd065a3d1768401eb00fabsalomon    if (!texture) {
144681beccc4fb1396fe94af15bfce26e68b82b93809bsalomon        return false;
144781beccc4fb1396fe94af15bfce26e68b82b93809bsalomon    }
14486f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com
144981beccc4fb1396fe94af15bfce26e68b82b93809bsalomon    SkAutoTUnref<const GrFragmentProcessor> fp;
145081beccc4fb1396fe94af15bfce26e68b82b93809bsalomon    SkMatrix textureMatrix;
145181beccc4fb1396fe94af15bfce26e68b82b93809bsalomon    textureMatrix.setIDiv(texture->width(), texture->height());
14523f80dd5f01a194d4fd9ce502734bc9f56bf3fb9fcommit-bot@chromium.org
145381beccc4fb1396fe94af15bfce26e68b82b93809bsalomon    // allocate a tmp buffer and sw convert the pixels to premul
145481beccc4fb1396fe94af15bfce26e68b82b93809bsalomon    SkAutoSTMalloc<128 * 128, uint32_t> tmpPixels(0);
145581beccc4fb1396fe94af15bfce26e68b82b93809bsalomon
145681beccc4fb1396fe94af15bfce26e68b82b93809bsalomon    if (kUnpremul_PixelOpsFlag & pixelOpsFlags) {
145781beccc4fb1396fe94af15bfce26e68b82b93809bsalomon        if (!GrPixelConfigIs8888(srcConfig)) {
145881beccc4fb1396fe94af15bfce26e68b82b93809bsalomon            return false;
145981beccc4fb1396fe94af15bfce26e68b82b93809bsalomon        }
146081beccc4fb1396fe94af15bfce26e68b82b93809bsalomon        fp.reset(this->createUPMToPMEffect(texture, swapRAndB, textureMatrix));
146181beccc4fb1396fe94af15bfce26e68b82b93809bsalomon        // handle the unpremul step on the CPU if we couldn't create an effect to do it.
146281beccc4fb1396fe94af15bfce26e68b82b93809bsalomon        if (NULL == fp) {
146381beccc4fb1396fe94af15bfce26e68b82b93809bsalomon            size_t tmpRowBytes = 4 * width;
146481beccc4fb1396fe94af15bfce26e68b82b93809bsalomon            tmpPixels.reset(width * height);
146581beccc4fb1396fe94af15bfce26e68b82b93809bsalomon            if (!sw_convert_to_premul(srcConfig, width, height, rowBytes, buffer, tmpRowBytes,
146681beccc4fb1396fe94af15bfce26e68b82b93809bsalomon                                      tmpPixels.get())) {
146781beccc4fb1396fe94af15bfce26e68b82b93809bsalomon                return false;
146881beccc4fb1396fe94af15bfce26e68b82b93809bsalomon            }
146981beccc4fb1396fe94af15bfce26e68b82b93809bsalomon            rowBytes = tmpRowBytes;
147081beccc4fb1396fe94af15bfce26e68b82b93809bsalomon            buffer = tmpPixels.get();
14713f80dd5f01a194d4fd9ce502734bc9f56bf3fb9fcommit-bot@chromium.org        }
147281beccc4fb1396fe94af15bfce26e68b82b93809bsalomon    }
147381beccc4fb1396fe94af15bfce26e68b82b93809bsalomon    if (NULL == fp) {
147481beccc4fb1396fe94af15bfce26e68b82b93809bsalomon        fp.reset(GrConfigConversionEffect::Create(texture,
147581beccc4fb1396fe94af15bfce26e68b82b93809bsalomon                                                  swapRAndB,
147681beccc4fb1396fe94af15bfce26e68b82b93809bsalomon                                                  GrConfigConversionEffect::kNone_PMConversion,
147781beccc4fb1396fe94af15bfce26e68b82b93809bsalomon                                                  textureMatrix));
147881beccc4fb1396fe94af15bfce26e68b82b93809bsalomon    }
1479583b18a20959c9ac360316a366f4ddd9598bdf52skia.committer@gmail.com
148081beccc4fb1396fe94af15bfce26e68b82b93809bsalomon    // Even if the client told us not to flush, we still flush here. The client may have known that
148181beccc4fb1396fe94af15bfce26e68b82b93809bsalomon    // writes to the original surface caused no data hazards, but they can't know that the scratch
148281beccc4fb1396fe94af15bfce26e68b82b93809bsalomon    // we just got is safe.
148381beccc4fb1396fe94af15bfce26e68b82b93809bsalomon    if (texture->surfacePriv().hasPendingIO()) {
148481beccc4fb1396fe94af15bfce26e68b82b93809bsalomon        this->flush();
148581beccc4fb1396fe94af15bfce26e68b82b93809bsalomon    }
148681beccc4fb1396fe94af15bfce26e68b82b93809bsalomon    if (!fGpu->writeTexturePixels(texture, 0, 0, width, height,
148781beccc4fb1396fe94af15bfce26e68b82b93809bsalomon                                  writeConfig, buffer, rowBytes)) {
1488669fdc4ed8ed461a141cb97d0afdd9ef72a82be1bsalomon@google.com        return false;
1489669fdc4ed8ed461a141cb97d0afdd9ef72a82be1bsalomon@google.com    }
1490669fdc4ed8ed461a141cb97d0afdd9ef72a82be1bsalomon@google.com
149181beccc4fb1396fe94af15bfce26e68b82b93809bsalomon    SkMatrix matrix;
149281beccc4fb1396fe94af15bfce26e68b82b93809bsalomon    matrix.setTranslate(SkIntToScalar(left), SkIntToScalar(top));
149381beccc4fb1396fe94af15bfce26e68b82b93809bsalomon
149481beccc4fb1396fe94af15bfce26e68b82b93809bsalomon    // This function can be called in the midst of drawing another object (e.g., when uploading a
149581beccc4fb1396fe94af15bfce26e68b82b93809bsalomon    // SW-rasterized clip while issuing a draw). So we push the current geometry state before
149681beccc4fb1396fe94af15bfce26e68b82b93809bsalomon    // drawing a rect to the render target.
149781beccc4fb1396fe94af15bfce26e68b82b93809bsalomon    // The bracket ensures we pop the stack if we wind up flushing below.
149881beccc4fb1396fe94af15bfce26e68b82b93809bsalomon    {
1499570d2f81a65fc868d6300a7edf34c0d5d048c5d6joshualitt        GrDrawTarget* drawTarget = this->prepareToDraw();
1500570d2f81a65fc868d6300a7edf34c0d5d048c5d6joshualitt        if (!drawTarget) {
1501570d2f81a65fc868d6300a7edf34c0d5d048c5d6joshualitt            return false;
1502570d2f81a65fc868d6300a7edf34c0d5d048c5d6joshualitt        }
15039853ccef19c200be93a6211f32589fa82a53067cjoshualitt
15048dd688b7569df569a672a8a67b2db86a9d376cfcegdaniel        GrPipelineBuilder pipelineBuilder;
15058dd688b7569df569a672a8a67b2db86a9d376cfcegdaniel        pipelineBuilder.addColorProcessor(fp);
15068dd688b7569df569a672a8a67b2db86a9d376cfcegdaniel        pipelineBuilder.setRenderTarget(renderTarget);
150744701df5ce572ac3cccec785cf52103d3d5d14a5joshualitt        drawTarget->drawSimpleRect(&pipelineBuilder,
150844701df5ce572ac3cccec785cf52103d3d5d14a5joshualitt                                   GrColor_WHITE,
150944701df5ce572ac3cccec785cf52103d3d5d14a5joshualitt                                   matrix,
15108059eb9f6e24ed609393fbda4ad71edea03ac258joshualitt                                   SkRect::MakeWH(SkIntToScalar(width), SkIntToScalar(height)));
151181beccc4fb1396fe94af15bfce26e68b82b93809bsalomon    }
151281beccc4fb1396fe94af15bfce26e68b82b93809bsalomon
151381beccc4fb1396fe94af15bfce26e68b82b93809bsalomon    if (kFlushWrites_PixelOp & pixelOpsFlags) {
151481beccc4fb1396fe94af15bfce26e68b82b93809bsalomon        this->flushSurfaceWrites(surface);
151581beccc4fb1396fe94af15bfce26e68b82b93809bsalomon    }
151681beccc4fb1396fe94af15bfce26e68b82b93809bsalomon
151781beccc4fb1396fe94af15bfce26e68b82b93809bsalomon    return true;
151881beccc4fb1396fe94af15bfce26e68b82b93809bsalomon}
1519a91e923874ca0565b4f4816b5697dfdcd337b889bsalomon@google.com
15207111d463cee893a479280c7af41757e709e33ef5reed@google.com// toggles between RGBA and BGRA
15217111d463cee893a479280c7af41757e709e33ef5reed@google.comstatic SkColorType toggle_colortype32(SkColorType ct) {
15227111d463cee893a479280c7af41757e709e33ef5reed@google.com    if (kRGBA_8888_SkColorType == ct) {
15237111d463cee893a479280c7af41757e709e33ef5reed@google.com        return kBGRA_8888_SkColorType;
15247111d463cee893a479280c7af41757e709e33ef5reed@google.com    } else {
15257111d463cee893a479280c7af41757e709e33ef5reed@google.com        SkASSERT(kBGRA_8888_SkColorType == ct);
15267111d463cee893a479280c7af41757e709e33ef5reed@google.com        return kRGBA_8888_SkColorType;
1527231f6b81c22001cac4ea87ea412c4d6fd10ffb8acommit-bot@chromium.org    }
1528231f6b81c22001cac4ea87ea412c4d6fd10ffb8acommit-bot@chromium.org}
1529231f6b81c22001cac4ea87ea412c4d6fd10ffb8acommit-bot@chromium.org
15300342a85091fd430c90a142d155dc9642aa729d9ebsalomon@google.combool GrContext::readRenderTargetPixels(GrRenderTarget* target,
15310342a85091fd430c90a142d155dc9642aa729d9ebsalomon@google.com                                       int left, int top, int width, int height,
15329c68058b679aee81e6e0158e7fcbfb5d8479c91absalomon@google.com                                       GrPixelConfig dstConfig, void* buffer, size_t rowBytes,
15330342a85091fd430c90a142d155dc9642aa729d9ebsalomon@google.com                                       uint32_t flags) {
15345f5a8d7599b8e248633ac122294b7a01401fedcbjoshualitt    RETURN_FALSE_IF_ABANDONED
1535bc4b654af85fa67bdd9cc1b88747b8c394a00e27bsalomon@google.com    ASSERT_OWNED_RESOURCE(target);
153689c62980c1eb50b2090f33312086c7e8c66739b4bsalomon    SkASSERT(target);
1537669fdc4ed8ed461a141cb97d0afdd9ef72a82be1bsalomon@google.com
1538afbf2d6273cd22c683f20a7e5773843876af3085bsalomon    if (!(kDontFlush_PixelOpsFlag & flags) && target->surfacePriv().hasPendingWrite()) {
15396f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com        this->flush();
15406f3795105b2b458079e53a721c1735c9518f6bb5bsalomon@google.com    }
1541c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com
1542a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com    // Determine which conversions have to be applied: flipY, swapRAnd, and/or unpremul.
1543c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com
1544a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com    // If fGpu->readPixels would incur a y-flip cost then we will read the pixels upside down. We'll
1545a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com    // either do the flipY by drawing into a scratch with a matrix or on the cpu after the read.
1546a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com    bool flipY = fGpu->readPixelsWillPayForYFlip(target, left, top,
15479c68058b679aee81e6e0158e7fcbfb5d8479c91absalomon@google.com                                                 width, height, dstConfig,
1548c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com                                                 rowBytes);
15499c68058b679aee81e6e0158e7fcbfb5d8479c91absalomon@google.com    // We ignore the preferred config if it is different than our config unless it is an R/B swap.
15509c68058b679aee81e6e0158e7fcbfb5d8479c91absalomon@google.com    // In that case we'll perform an R and B swap while drawing to a scratch texture of the swapped
15519c68058b679aee81e6e0158e7fcbfb5d8479c91absalomon@google.com    // config. Then we will call readPixels on the scratch with the swapped config. The swaps during
15529c68058b679aee81e6e0158e7fcbfb5d8479c91absalomon@google.com    // the draw cancels out the fact that we call readPixels with a config that is R/B swapped from
15539c68058b679aee81e6e0158e7fcbfb5d8479c91absalomon@google.com    // dstConfig.
15549c68058b679aee81e6e0158e7fcbfb5d8479c91absalomon@google.com    GrPixelConfig readConfig = dstConfig;
15559c68058b679aee81e6e0158e7fcbfb5d8479c91absalomon@google.com    bool swapRAndB = false;
15565d1d79a1f9d351e6f2390d844e6a7361d7d607cacommit-bot@chromium.org    if (GrPixelConfigSwapRAndB(dstConfig) ==
15575d1d79a1f9d351e6f2390d844e6a7361d7d607cacommit-bot@chromium.org        fGpu->preferredReadPixelsConfig(dstConfig, target->config())) {
15589c68058b679aee81e6e0158e7fcbfb5d8479c91absalomon@google.com        readConfig = GrPixelConfigSwapRAndB(readConfig);
15599c68058b679aee81e6e0158e7fcbfb5d8479c91absalomon@google.com        swapRAndB = true;
15609c68058b679aee81e6e0158e7fcbfb5d8479c91absalomon@google.com    }
1561a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com
15620342a85091fd430c90a142d155dc9642aa729d9ebsalomon@google.com    bool unpremul = SkToBool(kUnpremul_PixelOpsFlag & flags);
1563c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com
15649c68058b679aee81e6e0158e7fcbfb5d8479c91absalomon@google.com    if (unpremul && !GrPixelConfigIs8888(dstConfig)) {
1565a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com        // The unpremul flag is only allowed for these two configs.
15660a97be216df494291fe929b79d438809af7e9c83bsalomon@google.com        return false;
15670a97be216df494291fe929b79d438809af7e9c83bsalomon@google.com    }
1568a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com
1569191bcc008ea6b4cc445e105f6d36cbc057246e29bsalomon    SkAutoTUnref<GrTexture> tempTexture;
1570191bcc008ea6b4cc445e105f6d36cbc057246e29bsalomon
1571a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com    // If the src is a texture and we would have to do conversions after read pixels, we instead
1572a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com    // do the conversions by drawing the src to a scratch texture. If we handle any of the
1573a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com    // conversions in the draw we set the corresponding bool to false so that we don't reapply it
1574a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com    // on the read back pixels.
1575a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com    GrTexture* src = target->asTexture();
157649f085dddff10473b6ebf832a974288300224e60bsalomon    if (src && (swapRAndB || unpremul || flipY)) {
157781beccc4fb1396fe94af15bfce26e68b82b93809bsalomon        // Make the scratch a render so we can read its pixels.
1578f2703d83da3ab2ae18b45231fd4f11e16cce3184bsalomon        GrSurfaceDesc desc;
1579f2703d83da3ab2ae18b45231fd4f11e16cce3184bsalomon        desc.fFlags = kRenderTarget_GrSurfaceFlag;
158075b3c9633cb9a594dab0ccf51dab1e694c149a18robertphillips@google.com        desc.fWidth = width;
158175b3c9633cb9a594dab0ccf51dab1e694c149a18robertphillips@google.com        desc.fHeight = height;
1582a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com        desc.fConfig = readConfig;
15833cb406bb88f5aa09cf9f5a9554b4b1314cf1a2eesenorblanco@chromium.org        desc.fOrigin = kTopLeft_GrSurfaceOrigin;
1584c4ff22a2965616629765b8ffe0e58f6d05f92fa3bsalomon@google.com
15859c68058b679aee81e6e0158e7fcbfb5d8479c91absalomon@google.com        // When a full read back is faster than a partial we could always make the scratch exactly
1586a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com        // match the passed rect. However, if we see many different size rectangles we will trash
1587a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com        // our texture cache and pay the cost of creating and destroying many textures. So, we only
1588a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com        // request an exact match when the caller is reading an entire RT.
1589d309e7aa0efa2d5dd7e7b1af97026fcd3a047e98bsalomon        GrTextureProvider::ScratchTexMatch match = GrTextureProvider::kApprox_ScratchTexMatch;
159056d11e097b1975371d0e0b1452ac0c4d5fc46930bsalomon@google.com        if (0 == left &&
159156d11e097b1975371d0e0b1452ac0c4d5fc46930bsalomon@google.com            0 == top &&
159256d11e097b1975371d0e0b1452ac0c4d5fc46930bsalomon@google.com            target->width() == width &&
159356d11e097b1975371d0e0b1452ac0c4d5fc46930bsalomon@google.com            target->height() == height &&
159456d11e097b1975371d0e0b1452ac0c4d5fc46930bsalomon@google.com            fGpu->fullReadPixelsIsFasterThanPartial()) {
1595d309e7aa0efa2d5dd7e7b1af97026fcd3a047e98bsalomon            match = GrTextureProvider::kExact_ScratchTexMatch;
159656d11e097b1975371d0e0b1452ac0c4d5fc46930bsalomon@google.com        }
1597d309e7aa0efa2d5dd7e7b1af97026fcd3a047e98bsalomon        tempTexture.reset(this->textureProvider()->refScratchTexture(desc, match));
1598191bcc008ea6b4cc445e105f6d36cbc057246e29bsalomon        if (tempTexture) {
1599d8b5faca043100d7a1e4594b4d10e462532af390bsalomon@google.com            // compute a matrix to perform the draw
1600b9086a026844e4cfd08b219e49ce3f12294cba98bsalomon@google.com            SkMatrix textureMatrix;
16013cb406bb88f5aa09cf9f5a9554b4b1314cf1a2eesenorblanco@chromium.org            textureMatrix.setTranslate(SK_Scalar1 *left, SK_Scalar1 *top);
1602d8b5faca043100d7a1e4594b4d10e462532af390bsalomon@google.com            textureMatrix.postIDiv(src->width(), src->height());
1603d8b5faca043100d7a1e4594b4d10e462532af390bsalomon@google.com
1604b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt            SkAutoTUnref<const GrFragmentProcessor> fp;
1605a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com            if (unpremul) {
1606b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt                fp.reset(this->createPMToUPMEffect(src, swapRAndB, textureMatrix));
1607b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt                if (fp) {
16089c68058b679aee81e6e0158e7fcbfb5d8479c91absalomon@google.com                    unpremul = false; // we no longer need to do this on CPU after the read back.
1609d8b5faca043100d7a1e4594b4d10e462532af390bsalomon@google.com                }
1610a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com            }
1611a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com            // If we failed to create a PM->UPM effect and have no other conversions to perform then
1612a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com            // there is no longer any point to using the scratch.
1613b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt            if (fp || flipY || swapRAndB) {
1614b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt                if (!fp) {
1615b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt                    fp.reset(GrConfigConversionEffect::Create(
1616b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt                            src, swapRAndB, GrConfigConversionEffect::kNone_PMConversion,
1617b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt                            textureMatrix));
1618a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com                }
1619a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com                swapRAndB = false; // we will handle the swap in the draw.
1620a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com
162113f181f28f4336adcc93b7297b6d16503f4c323crobertphillips@google.com                // We protect the existing geometry here since it may not be
162213f181f28f4336adcc93b7297b6d16503f4c323crobertphillips@google.com                // clear to the caller that a draw operation (i.e., drawSimpleRect)
162313f181f28f4336adcc93b7297b6d16503f4c323crobertphillips@google.com                // can be invoked in this method
16245c55fef032d1de01fed6b40ac39081aea9544a75joshualitt                {
16258dd688b7569df569a672a8a67b2db86a9d376cfcegdaniel                    GrPipelineBuilder pipelineBuilder;
16265c55fef032d1de01fed6b40ac39081aea9544a75joshualitt                    SkASSERT(fp);
16278dd688b7569df569a672a8a67b2db86a9d376cfcegdaniel                    pipelineBuilder.addColorProcessor(fp);
16285c55fef032d1de01fed6b40ac39081aea9544a75joshualitt
16298dd688b7569df569a672a8a67b2db86a9d376cfcegdaniel                    pipelineBuilder.setRenderTarget(tempTexture->asRenderTarget());
16305c55fef032d1de01fed6b40ac39081aea9544a75joshualitt                    SkRect rect = SkRect::MakeWH(SkIntToScalar(width), SkIntToScalar(height));
163144701df5ce572ac3cccec785cf52103d3d5d14a5joshualitt                    fDrawBuffer->drawSimpleRect(&pipelineBuilder,
163244701df5ce572ac3cccec785cf52103d3d5d14a5joshualitt                                                GrColor_WHITE,
163344701df5ce572ac3cccec785cf52103d3d5d14a5joshualitt                                                SkMatrix::I(),
16348dd688b7569df569a672a8a67b2db86a9d376cfcegdaniel                                                rect);
16355c55fef032d1de01fed6b40ac39081aea9544a75joshualitt                    // we want to read back from the scratch's origin
16365c55fef032d1de01fed6b40ac39081aea9544a75joshualitt                    left = 0;
16375c55fef032d1de01fed6b40ac39081aea9544a75joshualitt                    top = 0;
1638191bcc008ea6b4cc445e105f6d36cbc057246e29bsalomon                    target = tempTexture->asRenderTarget();
16395c55fef032d1de01fed6b40ac39081aea9544a75joshualitt                }
16405c55fef032d1de01fed6b40ac39081aea9544a75joshualitt                this->flushSurfaceWrites(target);
1641a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com            }
1642c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com        }
1643a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com    }
16445c55fef032d1de01fed6b40ac39081aea9544a75joshualitt
1645a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com    if (!fGpu->readPixels(target,
1646a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com                          left, top, width, height,
16473cb406bb88f5aa09cf9f5a9554b4b1314cf1a2eesenorblanco@chromium.org                          readConfig, buffer, rowBytes)) {
1648a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com        return false;
1649a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com    }
1650d8b5faca043100d7a1e4594b4d10e462532af390bsalomon@google.com    // Perform any conversions we weren't able to perform using a scratch texture.
16513cb406bb88f5aa09cf9f5a9554b4b1314cf1a2eesenorblanco@chromium.org    if (unpremul || swapRAndB) {
16527111d463cee893a479280c7af41757e709e33ef5reed@google.com        SkDstPixelInfo dstPI;
1653fa1e8a7cefd71f7b75f0b85f8eefe111814dd86fjvanverth        if (!GrPixelConfig2ColorAndProfileType(dstConfig, &dstPI.fColorType, NULL)) {
16547111d463cee893a479280c7af41757e709e33ef5reed@google.com            return false;
16557111d463cee893a479280c7af41757e709e33ef5reed@google.com        }
16567111d463cee893a479280c7af41757e709e33ef5reed@google.com        dstPI.fAlphaType = kUnpremul_SkAlphaType;
16577111d463cee893a479280c7af41757e709e33ef5reed@google.com        dstPI.fPixels = buffer;
16587111d463cee893a479280c7af41757e709e33ef5reed@google.com        dstPI.fRowBytes = rowBytes;
1659be41d38f1c076c9e4dc595a6e1a4eb5ccdbd307bskia.committer@gmail.com
16607111d463cee893a479280c7af41757e709e33ef5reed@google.com        SkSrcPixelInfo srcPI;
16617111d463cee893a479280c7af41757e709e33ef5reed@google.com        srcPI.fColorType = swapRAndB ? toggle_colortype32(dstPI.fColorType) : dstPI.fColorType;
16627111d463cee893a479280c7af41757e709e33ef5reed@google.com        srcPI.fAlphaType = kPremul_SkAlphaType;
16637111d463cee893a479280c7af41757e709e33ef5reed@google.com        srcPI.fPixels = buffer;
16647111d463cee893a479280c7af41757e709e33ef5reed@google.com        srcPI.fRowBytes = rowBytes;
1665be41d38f1c076c9e4dc595a6e1a4eb5ccdbd307bskia.committer@gmail.com
16667111d463cee893a479280c7af41757e709e33ef5reed@google.com        return srcPI.convertPixelsTo(&dstPI, width, height);
1667c43649962221c348d656d425a3fa9b29c78231d4bsalomon@google.com    }
1668a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com    return true;
166927847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com}
167027847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com
167187a94eb1632d06eeeb89490a91565e786440d6d0bsalomonvoid GrContext::prepareSurfaceForExternalRead(GrSurface* surface) {
16725f5a8d7599b8e248633ac122294b7a01401fedcbjoshualitt    RETURN_IF_ABANDONED
167387a94eb1632d06eeeb89490a91565e786440d6d0bsalomon    SkASSERT(surface);
167487a94eb1632d06eeeb89490a91565e786440d6d0bsalomon    ASSERT_OWNED_RESOURCE(surface);
167587a94eb1632d06eeeb89490a91565e786440d6d0bsalomon    if (surface->surfacePriv().hasPendingIO()) {
167687a94eb1632d06eeeb89490a91565e786440d6d0bsalomon        this->flush();
167787a94eb1632d06eeeb89490a91565e786440d6d0bsalomon    }
167887a94eb1632d06eeeb89490a91565e786440d6d0bsalomon    GrRenderTarget* rt = surface->asRenderTarget();
167987a94eb1632d06eeeb89490a91565e786440d6d0bsalomon    if (fGpu && rt) {
168087a94eb1632d06eeeb89490a91565e786440d6d0bsalomon        fGpu->resolveRenderTarget(rt);
168141ebbddd76b747d5fb32c02dda0de3d03a3edda5bsalomon    }
168275f9f25d8bf2adc0494f9afbbd5965809ee13acabsalomon@google.com}
168375f9f25d8bf2adc0494f9afbbd5965809ee13acabsalomon@google.com
168441ebbddd76b747d5fb32c02dda0de3d03a3edda5bsalomonvoid GrContext::discardRenderTarget(GrRenderTarget* renderTarget) {
16855f5a8d7599b8e248633ac122294b7a01401fedcbjoshualitt    RETURN_IF_ABANDONED
168641ebbddd76b747d5fb32c02dda0de3d03a3edda5bsalomon    SkASSERT(renderTarget);
168741ebbddd76b747d5fb32c02dda0de3d03a3edda5bsalomon    ASSERT_OWNED_RESOURCE(renderTarget);
1688f21dab95405979a4aff9f6a741c818304a67f220bsalomon    AutoCheckFlush acf(this);
1689570d2f81a65fc868d6300a7edf34c0d5d048c5d6joshualitt    GrDrawTarget* target = this->prepareToDraw();
169041ebbddd76b747d5fb32c02dda0de3d03a3edda5bsalomon    if (NULL == target) {
169141ebbddd76b747d5fb32c02dda0de3d03a3edda5bsalomon        return;
169241ebbddd76b747d5fb32c02dda0de3d03a3edda5bsalomon    }
169341ebbddd76b747d5fb32c02dda0de3d03a3edda5bsalomon    target->discard(renderTarget);
169428361fad1054d59ed4e6a320c7a8b8782a1487c7commit-bot@chromium.org}
169528361fad1054d59ed4e6a320c7a8b8782a1487c7commit-bot@chromium.org
1696f80bfedc42fde88ae3f8dbd7b21950a22258fd22bsalomonvoid GrContext::copySurface(GrSurface* dst, GrSurface* src, const SkIRect& srcRect,
1697f80bfedc42fde88ae3f8dbd7b21950a22258fd22bsalomon                            const SkIPoint& dstPoint, uint32_t pixelOpsFlags) {
16985f5a8d7599b8e248633ac122294b7a01401fedcbjoshualitt    RETURN_IF_ABANDONED
1699ef843cdcd1be858fe55cc99ff134ffbd080c9a51senorblanco@chromium.org    if (NULL == src || NULL == dst) {
1700ef843cdcd1be858fe55cc99ff134ffbd080c9a51senorblanco@chromium.org        return;
1701ef843cdcd1be858fe55cc99ff134ffbd080c9a51senorblanco@chromium.org    }
1702e3d4bf234a04e14b6b0f33e11b3e1132b560c145bsalomon    ASSERT_OWNED_RESOURCE(src);
17032bb52102b16cf197709797be5e2209868ee2dafejunov    ASSERT_OWNED_RESOURCE(dst);
170434a9895baf8b2bf95c4f6944a7914be1a74f1524Brian Salomon
1705f80bfedc42fde88ae3f8dbd7b21950a22258fd22bsalomon    // Since we're going to the draw target and not GPU, no need to check kNoFlush
1706f80bfedc42fde88ae3f8dbd7b21950a22258fd22bsalomon    // here.
170796c118edff293af93db0a2b1b6775428117924b1junov
1708570d2f81a65fc868d6300a7edf34c0d5d048c5d6joshualitt    GrDrawTarget* target = this->prepareToDraw();
170996c118edff293af93db0a2b1b6775428117924b1junov    if (NULL == target) {
171096c118edff293af93db0a2b1b6775428117924b1junov        return;
171196c118edff293af93db0a2b1b6775428117924b1junov    }
171296c118edff293af93db0a2b1b6775428117924b1junov    target->copySurface(dst, src, srcRect, dstPoint);
1713f80bfedc42fde88ae3f8dbd7b21950a22258fd22bsalomon
1714f80bfedc42fde88ae3f8dbd7b21950a22258fd22bsalomon    if (kFlushWrites_PixelOp & pixelOpsFlags) {
1715f80bfedc42fde88ae3f8dbd7b21950a22258fd22bsalomon        this->flush();
1716f80bfedc42fde88ae3f8dbd7b21950a22258fd22bsalomon    }
1717ef843cdcd1be858fe55cc99ff134ffbd080c9a51senorblanco@chromium.org}
1718ef843cdcd1be858fe55cc99ff134ffbd080c9a51senorblanco@chromium.org
1719f80bfedc42fde88ae3f8dbd7b21950a22258fd22bsalomonvoid GrContext::flushSurfaceWrites(GrSurface* surface) {
17205f5a8d7599b8e248633ac122294b7a01401fedcbjoshualitt    RETURN_IF_ABANDONED
1721f80bfedc42fde88ae3f8dbd7b21950a22258fd22bsalomon    if (surface->surfacePriv().hasPendingWrite()) {
1722f80bfedc42fde88ae3f8dbd7b21950a22258fd22bsalomon        this->flush();
1723f80bfedc42fde88ae3f8dbd7b21950a22258fd22bsalomon    }
1724f80bfedc42fde88ae3f8dbd7b21950a22258fd22bsalomon}
1725f80bfedc42fde88ae3f8dbd7b21950a22258fd22bsalomon
17268dd688b7569df569a672a8a67b2db86a9d376cfcegdanielGrDrawTarget* GrContext::prepareToDraw(GrPipelineBuilder* pipelineBuilder,
172725d9c154087d2132a51d1ca74a104726f60ef380joshualitt                                       GrRenderTarget* rt,
1728570d2f81a65fc868d6300a7edf34c0d5d048c5d6joshualitt                                       const GrClip& clip,
17299853ccef19c200be93a6211f32589fa82a53067cjoshualitt                                       const GrPaint* paint,
17309853ccef19c200be93a6211f32589fa82a53067cjoshualitt                                       const AutoCheckFlush* acf) {
17315f5a8d7599b8e248633ac122294b7a01401fedcbjoshualitt    if (NULL == fGpu || NULL == fDrawBuffer) {
173241ebbddd76b747d5fb32c02dda0de3d03a3edda5bsalomon        return NULL;
173341ebbddd76b747d5fb32c02dda0de3d03a3edda5bsalomon    }
173441ebbddd76b747d5fb32c02dda0de3d03a3edda5bsalomon
1735570d2f81a65fc868d6300a7edf34c0d5d048c5d6joshualitt    ASSERT_OWNED_RESOURCE(rt);
1736570d2f81a65fc868d6300a7edf34c0d5d048c5d6joshualitt    SkASSERT(rt && paint && acf);
1737570d2f81a65fc868d6300a7edf34c0d5d048c5d6joshualitt    pipelineBuilder->setFromPaint(*paint, rt, clip);
1738570d2f81a65fc868d6300a7edf34c0d5d048c5d6joshualitt    return fDrawBuffer;
1739570d2f81a65fc868d6300a7edf34c0d5d048c5d6joshualitt}
1740570d2f81a65fc868d6300a7edf34c0d5d048c5d6joshualitt
1741570d2f81a65fc868d6300a7edf34c0d5d048c5d6joshualittGrDrawTarget* GrContext::prepareToDraw() {
1742570d2f81a65fc868d6300a7edf34c0d5d048c5d6joshualitt    if (NULL == fGpu) {
1743570d2f81a65fc868d6300a7edf34c0d5d048c5d6joshualitt        return NULL;
174407ea2db0260d8e6cd2bf605571b68b1c574b5a77bsalomon@google.com    }
17455c55fef032d1de01fed6b40ac39081aea9544a75joshualitt    return fDrawBuffer;
174627847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com}
174727847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com
174872176b2d38db005863a54e3dd6657bbabd068bb6robertphillips@google.com/*
174972176b2d38db005863a54e3dd6657bbabd068bb6robertphillips@google.com * This method finds a path renderer that can draw the specified path on
175072176b2d38db005863a54e3dd6657bbabd068bb6robertphillips@google.com * the provided target.
1751fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com * Due to its expense, the software path renderer has split out so it can
175272176b2d38db005863a54e3dd6657bbabd068bb6robertphillips@google.com * can be individually allowed/disallowed via the "allowSW" boolean.
175372176b2d38db005863a54e3dd6657bbabd068bb6robertphillips@google.com */
17549853ccef19c200be93a6211f32589fa82a53067cjoshualittGrPathRenderer* GrContext::getPathRenderer(const GrDrawTarget* target,
17558dd688b7569df569a672a8a67b2db86a9d376cfcegdaniel                                           const GrPipelineBuilder* pipelineBuilder,
17568059eb9f6e24ed609393fbda4ad71edea03ac258joshualitt                                           const SkMatrix& viewMatrix,
17579853ccef19c200be93a6211f32589fa82a53067cjoshualitt                                           const SkPath& path,
17581899651ffc459f5462aa989cd6d08507947b67e4kkinnunen                                           const GrStrokeInfo& stroke,
175945a15f551b5b3c6c747d8eaf6466b7d3b76a8faebsalomon@google.com                                           bool allowSW,
176045a15f551b5b3c6c747d8eaf6466b7d3b76a8faebsalomon@google.com                                           GrPathRendererChain::DrawType drawType,
176145a15f551b5b3c6c747d8eaf6466b7d3b76a8faebsalomon@google.com                                           GrPathRendererChain::StencilSupport* stencilSupport) {
176245a15f551b5b3c6c747d8eaf6466b7d3b76a8faebsalomon@google.com
17633008519e9f977cd60194841d558a4f45c28e9833bsalomon@google.com    if (NULL == fPathRendererChain) {
176445a15f551b5b3c6c747d8eaf6466b7d3b76a8faebsalomon@google.com        fPathRendererChain = SkNEW_ARGS(GrPathRendererChain, (this));
17653008519e9f977cd60194841d558a4f45c28e9833bsalomon@google.com    }
176672176b2d38db005863a54e3dd6657bbabd068bb6robertphillips@google.com
17679853ccef19c200be93a6211f32589fa82a53067cjoshualitt    GrPathRenderer* pr = fPathRendererChain->getPathRenderer(target,
17688dd688b7569df569a672a8a67b2db86a9d376cfcegdaniel                                                             pipelineBuilder,
17698059eb9f6e24ed609393fbda4ad71edea03ac258joshualitt                                                             viewMatrix,
17709853ccef19c200be93a6211f32589fa82a53067cjoshualitt                                                             path,
177112b4e27ae1a29460e91a59f38122483e1faec697sugoi@google.com                                                             stroke,
177245a15f551b5b3c6c747d8eaf6466b7d3b76a8faebsalomon@google.com                                                             drawType,
177345a15f551b5b3c6c747d8eaf6466b7d3b76a8faebsalomon@google.com                                                             stencilSupport);
177472176b2d38db005863a54e3dd6657bbabd068bb6robertphillips@google.com
177572176b2d38db005863a54e3dd6657bbabd068bb6robertphillips@google.com    if (NULL == pr && allowSW) {
177672176b2d38db005863a54e3dd6657bbabd068bb6robertphillips@google.com        if (NULL == fSoftwarePathRenderer) {
1777c377baf406996aed18d82d328029c82dbc3b8ddatomhudson@google.com            fSoftwarePathRenderer = SkNEW_ARGS(GrSoftwarePathRenderer, (this));
177872176b2d38db005863a54e3dd6657bbabd068bb6robertphillips@google.com        }
177972176b2d38db005863a54e3dd6657bbabd068bb6robertphillips@google.com        pr = fSoftwarePathRenderer;
178072176b2d38db005863a54e3dd6657bbabd068bb6robertphillips@google.com    }
178172176b2d38db005863a54e3dd6657bbabd068bb6robertphillips@google.com
178272176b2d38db005863a54e3dd6657bbabd068bb6robertphillips@google.com    return pr;
17833008519e9f977cd60194841d558a4f45c28e9833bsalomon@google.com}
17843008519e9f977cd60194841d558a4f45c28e9833bsalomon@google.com
178527847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com////////////////////////////////////////////////////////////////////////////////
17866b7938f9cb250086a7c6325cf31576f894ca4a1bcommit-bot@chromium.orgbool GrContext::isConfigRenderable(GrPixelConfig config, bool withMSAA) const {
17876b7938f9cb250086a7c6325cf31576f894ca4a1bcommit-bot@chromium.org    return fGpu->caps()->isConfigRenderable(config, withMSAA);
178899a5ac0b67a14048a1db3f429878775854d29397robertphillips@google.com}
178999a5ac0b67a14048a1db3f429878775854d29397robertphillips@google.com
1790b471a32460a44043e1f00d28cbefc87579dc30c5commit-bot@chromium.orgint GrContext::getRecommendedSampleCount(GrPixelConfig config,
1791b471a32460a44043e1f00d28cbefc87579dc30c5commit-bot@chromium.org                                         SkScalar dpi) const {
1792b471a32460a44043e1f00d28cbefc87579dc30c5commit-bot@chromium.org    if (!this->isConfigRenderable(config, true)) {
1793b471a32460a44043e1f00d28cbefc87579dc30c5commit-bot@chromium.org        return 0;
1794b471a32460a44043e1f00d28cbefc87579dc30c5commit-bot@chromium.org    }
1795b471a32460a44043e1f00d28cbefc87579dc30c5commit-bot@chromium.org    int chosenSampleCount = 0;
1796e9c0fc616d2a1632c285885b9b656b68ca8d4f24jvanverth    if (fGpu->caps()->shaderCaps()->pathRenderingSupport()) {
1797b471a32460a44043e1f00d28cbefc87579dc30c5commit-bot@chromium.org        if (dpi >= 250.0f) {
1798b471a32460a44043e1f00d28cbefc87579dc30c5commit-bot@chromium.org            chosenSampleCount = 4;
1799b471a32460a44043e1f00d28cbefc87579dc30c5commit-bot@chromium.org        } else {
1800b471a32460a44043e1f00d28cbefc87579dc30c5commit-bot@chromium.org            chosenSampleCount = 16;
1801b471a32460a44043e1f00d28cbefc87579dc30c5commit-bot@chromium.org        }
1802b471a32460a44043e1f00d28cbefc87579dc30c5commit-bot@chromium.org    }
1803b471a32460a44043e1f00d28cbefc87579dc30c5commit-bot@chromium.org    return chosenSampleCount <= fGpu->caps()->maxSampleCount() ?
1804b471a32460a44043e1f00d28cbefc87579dc30c5commit-bot@chromium.org        chosenSampleCount : 0;
1805b471a32460a44043e1f00d28cbefc87579dc30c5commit-bot@chromium.org}
1806b471a32460a44043e1f00d28cbefc87579dc30c5commit-bot@chromium.org
180721c10c5ff50cb8f2fd995fc9396d435d3396258bbsalomon@google.comGrDrawTarget* GrContext::getTextTarget() {
1808570d2f81a65fc868d6300a7edf34c0d5d048c5d6joshualitt    return this->prepareToDraw();
180927847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com}
181027847dedd9b5c1f48998c40842f3494c0746257fbsalomon@google.com
1811a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.comnamespace {
1812a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.comvoid test_pm_conversions(GrContext* ctx, int* pmToUPMValue, int* upmToPMValue) {
1813a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com    GrConfigConversionEffect::PMConversion pmToUPM;
1814a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com    GrConfigConversionEffect::PMConversion upmToPM;
1815a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com    GrConfigConversionEffect::TestForPreservingPMConversions(ctx, &pmToUPM, &upmToPM);
1816a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com    *pmToUPMValue = pmToUPM;
1817a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com    *upmToPMValue = upmToPM;
1818a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com}
1819a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com}
1820a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com
1821b0a8a377f832c59cee939ad721e1f87d378b7142joshualittconst GrFragmentProcessor* GrContext::createPMToUPMEffect(GrTexture* texture,
1822b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt                                                          bool swapRAndB,
1823b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt                                                          const SkMatrix& matrix) {
1824a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com    if (!fDidTestPMConversions) {
1825a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com        test_pm_conversions(this, &fPMToUPMConversion, &fUPMToPMConversion);
1826d0f3f6825bd5c232da52f4dc1af69b76403b797fbsalomon@google.com        fDidTestPMConversions = true;
1827a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com    }
1828a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com    GrConfigConversionEffect::PMConversion pmToUPM =
1829a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com        static_cast<GrConfigConversionEffect::PMConversion>(fPMToUPMConversion);
1830a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com    if (GrConfigConversionEffect::kNone_PMConversion != pmToUPM) {
1831adc6536fe5baff2216fb76ecda6cc81c61109d5cbsalomon@google.com        return GrConfigConversionEffect::Create(texture, swapRAndB, pmToUPM, matrix);
1832a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com    } else {
1833adc6536fe5baff2216fb76ecda6cc81c61109d5cbsalomon@google.com        return NULL;
1834a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com    }
1835a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com}
1836a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com
1837b0a8a377f832c59cee939ad721e1f87d378b7142joshualittconst GrFragmentProcessor* GrContext::createUPMToPMEffect(GrTexture* texture,
1838b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt                                                          bool swapRAndB,
1839b0a8a377f832c59cee939ad721e1f87d378b7142joshualitt                                                          const SkMatrix& matrix) {
1840a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com    if (!fDidTestPMConversions) {
1841a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com        test_pm_conversions(this, &fPMToUPMConversion, &fUPMToPMConversion);
1842d0f3f6825bd5c232da52f4dc1af69b76403b797fbsalomon@google.com        fDidTestPMConversions = true;
1843a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com    }
1844a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com    GrConfigConversionEffect::PMConversion upmToPM =
1845a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com        static_cast<GrConfigConversionEffect::PMConversion>(fUPMToPMConversion);
1846a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com    if (GrConfigConversionEffect::kNone_PMConversion != upmToPM) {
1847adc6536fe5baff2216fb76ecda6cc81c61109d5cbsalomon@google.com        return GrConfigConversionEffect::Create(texture, swapRAndB, upmToPM, matrix);
1848a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com    } else {
1849adc6536fe5baff2216fb76ecda6cc81c61109d5cbsalomon@google.com        return NULL;
1850a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com    }
1851a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com}
1852a04e8e842450e606dd938ddae17857849bd504d4bsalomon@google.com
185337f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon//////////////////////////////////////////////////////////////////////////////
185437f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon
185537f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomonvoid GrContext::getResourceCacheLimits(int* maxTextures, size_t* maxTextureBytes) const {
185637f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon    if (maxTextures) {
18570ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon        *maxTextures = fResourceCache->getMaxResourceCount();
185837f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon    }
185937f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon    if (maxTextureBytes) {
18600ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon        *maxTextureBytes = fResourceCache->getMaxResourceBytes();
186137f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon    }
186237f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon}
186337f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon
186437f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomonvoid GrContext::setResourceCacheLimits(int maxTextures, size_t maxTextureBytes) {
18650ea80f43a1af05b8157a4ef387223bb5b0da35edbsalomon    fResourceCache->setLimits(maxTextures, maxTextureBytes);
186637f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon}
186737f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon
186837f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon//////////////////////////////////////////////////////////////////////////////
186937f9a2694c15f08e361ebda74fe9f0fffbf452aabsalomon
1870bbcb38df4f7477aa0a38da00a0757586a0125954egdanielvoid GrContext::addGpuTraceMarker(const GrGpuTraceMarker* marker) {
1871bbcb38df4f7477aa0a38da00a0757586a0125954egdaniel    fGpu->addGpuTraceMarker(marker);
187249f085dddff10473b6ebf832a974288300224e60bsalomon    if (fDrawBuffer) {
1873bbcb38df4f7477aa0a38da00a0757586a0125954egdaniel        fDrawBuffer->addGpuTraceMarker(marker);
1874bbcb38df4f7477aa0a38da00a0757586a0125954egdaniel    }
1875bbcb38df4f7477aa0a38da00a0757586a0125954egdaniel}
1876bbcb38df4f7477aa0a38da00a0757586a0125954egdaniel
1877bbcb38df4f7477aa0a38da00a0757586a0125954egdanielvoid GrContext::removeGpuTraceMarker(const GrGpuTraceMarker* marker) {
1878bbcb38df4f7477aa0a38da00a0757586a0125954egdaniel    fGpu->removeGpuTraceMarker(marker);
187949f085dddff10473b6ebf832a974288300224e60bsalomon    if (fDrawBuffer) {
1880bbcb38df4f7477aa0a38da00a0757586a0125954egdaniel        fDrawBuffer->removeGpuTraceMarker(marker);
1881bbcb38df4f7477aa0a38da00a0757586a0125954egdaniel    }
1882bbcb38df4f7477aa0a38da00a0757586a0125954egdaniel}
1883e590266294c4c92e4e4c2f06f267ac5751d07562joshualitt
1884e590266294c4c92e4e4c2f06f267ac5751d07562joshualitt///////////////////////////////////////////////////////////////////////////////////////////////////
1885e590266294c4c92e4e4c2f06f267ac5751d07562joshualitt
1886e590266294c4c92e4e4c2f06f267ac5751d07562joshualitt#ifdef GR_TEST_UTILS
1887e590266294c4c92e4e4c2f06f267ac5751d07562joshualitt
18886c891107ce0a8431f2327cb8b2f1bfd363cabbbejoshualittBATCH_TEST_DEFINE(StrokeRectBatch) {
1889e590266294c4c92e4e4c2f06f267ac5751d07562joshualitt    StrokeRectBatch::Geometry geometry;
1890e590266294c4c92e4e4c2f06f267ac5751d07562joshualitt    geometry.fViewMatrix = GrTest::TestMatrix(random);
1891e590266294c4c92e4e4c2f06f267ac5751d07562joshualitt    geometry.fColor = GrRandomColor(random);
1892e590266294c4c92e4e4c2f06f267ac5751d07562joshualitt    geometry.fRect = GrTest::TestRect(random);
1893e590266294c4c92e4e4c2f06f267ac5751d07562joshualitt    geometry.fStrokeWidth = random->nextBool() ? 0.0f : 1.0f;
1894e590266294c4c92e4e4c2f06f267ac5751d07562joshualitt
18954c977868bbe100d6d95f9e53cf176d611eceb3dcjoshualitt    return StrokeRectBatch::Create(geometry, random->nextBool());
1896e590266294c4c92e4e4c2f06f267ac5751d07562joshualitt}
1897e590266294c4c92e4e4c2f06f267ac5751d07562joshualitt
1898e590266294c4c92e4e4c2f06f267ac5751d07562joshualittstatic uint32_t seed_vertices(GrPrimitiveType type) {
1899e590266294c4c92e4e4c2f06f267ac5751d07562joshualitt    switch (type) {
1900e590266294c4c92e4e4c2f06f267ac5751d07562joshualitt        case kTriangles_GrPrimitiveType:
1901e590266294c4c92e4e4c2f06f267ac5751d07562joshualitt        case kTriangleStrip_GrPrimitiveType:
1902e590266294c4c92e4e4c2f06f267ac5751d07562joshualitt        case kTriangleFan_GrPrimitiveType:
1903e590266294c4c92e4e4c2f06f267ac5751d07562joshualitt            return 3;
1904e590266294c4c92e4e4c2f06f267ac5751d07562joshualitt        case kPoints_GrPrimitiveType:
1905e590266294c4c92e4e4c2f06f267ac5751d07562joshualitt            return 1;
1906e590266294c4c92e4e4c2f06f267ac5751d07562joshualitt        case kLines_GrPrimitiveType:
1907e590266294c4c92e4e4c2f06f267ac5751d07562joshualitt        case kLineStrip_GrPrimitiveType:
1908e590266294c4c92e4e4c2f06f267ac5751d07562joshualitt            return 2;
1909e590266294c4c92e4e4c2f06f267ac5751d07562joshualitt    }
1910e590266294c4c92e4e4c2f06f267ac5751d07562joshualitt    SkFAIL("Incomplete switch\n");
1911e590266294c4c92e4e4c2f06f267ac5751d07562joshualitt    return 0;
1912e590266294c4c92e4e4c2f06f267ac5751d07562joshualitt}
1913e590266294c4c92e4e4c2f06f267ac5751d07562joshualitt
1914e590266294c4c92e4e4c2f06f267ac5751d07562joshualittstatic uint32_t primitive_vertices(GrPrimitiveType type) {
1915e590266294c4c92e4e4c2f06f267ac5751d07562joshualitt    switch (type) {
1916e590266294c4c92e4e4c2f06f267ac5751d07562joshualitt        case kTriangles_GrPrimitiveType:
1917e590266294c4c92e4e4c2f06f267ac5751d07562joshualitt            return 3;
1918e590266294c4c92e4e4c2f06f267ac5751d07562joshualitt        case kLines_GrPrimitiveType:
1919e590266294c4c92e4e4c2f06f267ac5751d07562joshualitt            return 2;
1920e590266294c4c92e4e4c2f06f267ac5751d07562joshualitt        case kTriangleStrip_GrPrimitiveType:
1921e590266294c4c92e4e4c2f06f267ac5751d07562joshualitt        case kTriangleFan_GrPrimitiveType:
1922e590266294c4c92e4e4c2f06f267ac5751d07562joshualitt        case kPoints_GrPrimitiveType:
1923e590266294c4c92e4e4c2f06f267ac5751d07562joshualitt        case kLineStrip_GrPrimitiveType:
1924e590266294c4c92e4e4c2f06f267ac5751d07562joshualitt            return 1;
1925e590266294c4c92e4e4c2f06f267ac5751d07562joshualitt    }
1926e590266294c4c92e4e4c2f06f267ac5751d07562joshualitt    SkFAIL("Incomplete switch\n");
1927e590266294c4c92e4e4c2f06f267ac5751d07562joshualitt    return 0;
1928e590266294c4c92e4e4c2f06f267ac5751d07562joshualitt}
1929e590266294c4c92e4e4c2f06f267ac5751d07562joshualitt
1930e590266294c4c92e4e4c2f06f267ac5751d07562joshualittstatic SkPoint random_point(SkRandom* random, SkScalar min, SkScalar max) {
1931e590266294c4c92e4e4c2f06f267ac5751d07562joshualitt    SkPoint p;
1932e590266294c4c92e4e4c2f06f267ac5751d07562joshualitt    p.fX = random->nextRangeScalar(min, max);
1933e590266294c4c92e4e4c2f06f267ac5751d07562joshualitt    p.fY = random->nextRangeScalar(min, max);
1934e590266294c4c92e4e4c2f06f267ac5751d07562joshualitt    return p;
1935e590266294c4c92e4e4c2f06f267ac5751d07562joshualitt}
1936e590266294c4c92e4e4c2f06f267ac5751d07562joshualitt
1937e590266294c4c92e4e4c2f06f267ac5751d07562joshualittstatic void randomize_params(size_t count, size_t maxVertex, SkScalar min, SkScalar max,
1938e590266294c4c92e4e4c2f06f267ac5751d07562joshualitt                             SkRandom* random,
1939e590266294c4c92e4e4c2f06f267ac5751d07562joshualitt                             SkTArray<SkPoint>* positions,
1940e590266294c4c92e4e4c2f06f267ac5751d07562joshualitt                             SkTArray<SkPoint>* texCoords, bool hasTexCoords,
1941e590266294c4c92e4e4c2f06f267ac5751d07562joshualitt                             SkTArray<GrColor>* colors, bool hasColors,
1942e590266294c4c92e4e4c2f06f267ac5751d07562joshualitt                             SkTArray<uint16_t>* indices, bool hasIndices) {
1943e590266294c4c92e4e4c2f06f267ac5751d07562joshualitt    for (uint32_t v = 0; v < count; v++) {
1944e590266294c4c92e4e4c2f06f267ac5751d07562joshualitt        positions->push_back(random_point(random, min, max));
1945e590266294c4c92e4e4c2f06f267ac5751d07562joshualitt        if (hasTexCoords) {
1946e590266294c4c92e4e4c2f06f267ac5751d07562joshualitt            texCoords->push_back(random_point(random, min, max));
1947e590266294c4c92e4e4c2f06f267ac5751d07562joshualitt        }
1948e590266294c4c92e4e4c2f06f267ac5751d07562joshualitt        if (hasColors) {
1949e590266294c4c92e4e4c2f06f267ac5751d07562joshualitt            colors->push_back(GrRandomColor(random));
1950e590266294c4c92e4e4c2f06f267ac5751d07562joshualitt        }
1951e590266294c4c92e4e4c2f06f267ac5751d07562joshualitt        if (hasIndices) {
1952e590266294c4c92e4e4c2f06f267ac5751d07562joshualitt            SkASSERT(maxVertex <= SK_MaxU16);
1953e590266294c4c92e4e4c2f06f267ac5751d07562joshualitt            indices->push_back(random->nextULessThan((uint16_t)maxVertex));
1954e590266294c4c92e4e4c2f06f267ac5751d07562joshualitt        }
1955e590266294c4c92e4e4c2f06f267ac5751d07562joshualitt    }
1956e590266294c4c92e4e4c2f06f267ac5751d07562joshualitt}
1957e590266294c4c92e4e4c2f06f267ac5751d07562joshualitt
19586c891107ce0a8431f2327cb8b2f1bfd363cabbbejoshualittBATCH_TEST_DEFINE(VerticesBatch) {
1959e590266294c4c92e4e4c2f06f267ac5751d07562joshualitt    GrPrimitiveType type = GrPrimitiveType(random->nextULessThan(kLast_GrPrimitiveType + 1));
1960e590266294c4c92e4e4c2f06f267ac5751d07562joshualitt    uint32_t primitiveCount = random->nextRangeU(1, 100);
1961e590266294c4c92e4e4c2f06f267ac5751d07562joshualitt
1962e590266294c4c92e4e4c2f06f267ac5751d07562joshualitt    // TODO make 'sensible' indexbuffers
1963e590266294c4c92e4e4c2f06f267ac5751d07562joshualitt    SkTArray<SkPoint> positions;
1964e590266294c4c92e4e4c2f06f267ac5751d07562joshualitt    SkTArray<SkPoint> texCoords;
1965e590266294c4c92e4e4c2f06f267ac5751d07562joshualitt    SkTArray<GrColor> colors;
1966e590266294c4c92e4e4c2f06f267ac5751d07562joshualitt    SkTArray<uint16_t> indices;
1967e590266294c4c92e4e4c2f06f267ac5751d07562joshualitt
1968e590266294c4c92e4e4c2f06f267ac5751d07562joshualitt    bool hasTexCoords = random->nextBool();
1969e590266294c4c92e4e4c2f06f267ac5751d07562joshualitt    bool hasIndices = random->nextBool();
1970e590266294c4c92e4e4c2f06f267ac5751d07562joshualitt    bool hasColors = random->nextBool();
1971e590266294c4c92e4e4c2f06f267ac5751d07562joshualitt
1972e590266294c4c92e4e4c2f06f267ac5751d07562joshualitt    uint32_t vertexCount = seed_vertices(type) + (primitiveCount - 1) * primitive_vertices(type);
1973e590266294c4c92e4e4c2f06f267ac5751d07562joshualitt
1974e590266294c4c92e4e4c2f06f267ac5751d07562joshualitt    static const SkScalar kMinVertExtent = -100.f;
1975e590266294c4c92e4e4c2f06f267ac5751d07562joshualitt    static const SkScalar kMaxVertExtent = 100.f;
1976e590266294c4c92e4e4c2f06f267ac5751d07562joshualitt    randomize_params(seed_vertices(type), vertexCount, kMinVertExtent, kMaxVertExtent,
1977e590266294c4c92e4e4c2f06f267ac5751d07562joshualitt                     random,
1978e590266294c4c92e4e4c2f06f267ac5751d07562joshualitt                     &positions,
1979e590266294c4c92e4e4c2f06f267ac5751d07562joshualitt                     &texCoords, hasTexCoords,
1980e590266294c4c92e4e4c2f06f267ac5751d07562joshualitt                     &colors, hasColors,
1981e590266294c4c92e4e4c2f06f267ac5751d07562joshualitt                     &indices, hasIndices);
1982e590266294c4c92e4e4c2f06f267ac5751d07562joshualitt
1983e590266294c4c92e4e4c2f06f267ac5751d07562joshualitt    for (uint32_t i = 1; i < primitiveCount; i++) {
1984e590266294c4c92e4e4c2f06f267ac5751d07562joshualitt        randomize_params(primitive_vertices(type), vertexCount, kMinVertExtent, kMaxVertExtent,
1985e590266294c4c92e4e4c2f06f267ac5751d07562joshualitt                         random,
1986e590266294c4c92e4e4c2f06f267ac5751d07562joshualitt                         &positions,
1987e590266294c4c92e4e4c2f06f267ac5751d07562joshualitt                         &texCoords, hasTexCoords,
1988e590266294c4c92e4e4c2f06f267ac5751d07562joshualitt                         &colors, hasColors,
1989e590266294c4c92e4e4c2f06f267ac5751d07562joshualitt                         &indices, hasIndices);
1990e590266294c4c92e4e4c2f06f267ac5751d07562joshualitt    }
1991e590266294c4c92e4e4c2f06f267ac5751d07562joshualitt
1992e590266294c4c92e4e4c2f06f267ac5751d07562joshualitt    SkMatrix viewMatrix = GrTest::TestMatrix(random);
1993e590266294c4c92e4e4c2f06f267ac5751d07562joshualitt    SkRect bounds;
1994e590266294c4c92e4e4c2f06f267ac5751d07562joshualitt    SkDEBUGCODE(bool result = ) bounds.setBoundsCheck(positions.begin(), vertexCount);
1995e590266294c4c92e4e4c2f06f267ac5751d07562joshualitt    SkASSERT(result);
1996e590266294c4c92e4e4c2f06f267ac5751d07562joshualitt
1997e590266294c4c92e4e4c2f06f267ac5751d07562joshualitt    viewMatrix.mapRect(&bounds);
1998e590266294c4c92e4e4c2f06f267ac5751d07562joshualitt
1999e590266294c4c92e4e4c2f06f267ac5751d07562joshualitt    DrawVerticesBatch::Geometry geometry;
2000e590266294c4c92e4e4c2f06f267ac5751d07562joshualitt    geometry.fColor = GrRandomColor(random);
2001e590266294c4c92e4e4c2f06f267ac5751d07562joshualitt    return DrawVerticesBatch::Create(geometry, type, viewMatrix,
2002e590266294c4c92e4e4c2f06f267ac5751d07562joshualitt                                     positions.begin(), vertexCount,
2003e590266294c4c92e4e4c2f06f267ac5751d07562joshualitt                                     indices.begin(), hasIndices ? vertexCount : 0,
2004e590266294c4c92e4e4c2f06f267ac5751d07562joshualitt                                     colors.begin(),
2005e590266294c4c92e4e4c2f06f267ac5751d07562joshualitt                                     texCoords.begin(),
2006e590266294c4c92e4e4c2f06f267ac5751d07562joshualitt                                     bounds);
2007e590266294c4c92e4e4c2f06f267ac5751d07562joshualitt}
2008e590266294c4c92e4e4c2f06f267ac5751d07562joshualitt
2009e590266294c4c92e4e4c2f06f267ac5751d07562joshualitt#endif
2010