GrGpuGL_program.cpp revision 7839ce1af63bf12fe7b3caa866970bbbb3afb13d
180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru/*
280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * Copyright 2011 Google Inc.
380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru *
480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * Use of this source code is governed by a BSD-style license that can be
580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * found in the LICENSE file.
680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru */
780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include "GrGpuGL.h"
980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
10363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger#include "GrEffect.h"
11363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger#include "GrGLEffect.h"
1280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
1380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querutypedef GrGLUniformManager::UniformHandle UniformHandle;
1480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Querustatic const UniformHandle kInvalidUniformHandle = GrGLUniformManager::kInvalidUniformHandle;
1580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
1680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#define SKIP_CACHE_CHECK    true
1780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#define GR_UINT32_MAX   static_cast<uint32_t>(-1)
1880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
19096defe64d408e54474fe19f418c95bf1a554fc7Derek SollenbergerGrGpuGL::ProgramCache::ProgramCache(const GrGLContext& gl)
2080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    : fCount(0)
2180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    , fCurrLRUStamp(0)
22096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger    , fGL(gl)
23096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger#ifdef PROGRAM_CACHE_STATS
24096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger    , fTotalRequests(0)
25096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger    , fCacheMisses(0)
26096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger#endif
27096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger{
28096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger}
29096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger
30096defe64d408e54474fe19f418c95bf1a554fc7Derek SollenbergerGrGpuGL::ProgramCache::~ProgramCache() {
31096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger    // dump stats
32096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger#ifdef PROGRAM_CACHE_STATS
33096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger    SkDebugf("--- Program Cache ---\n");
34096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger    SkDebugf("Total requests: %d\n", fTotalRequests);
35096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger    SkDebugf("Cache misses: %d\n", fCacheMisses);
36e2022cc36e47b9f0d219eb5cd24be61772c28d3bDerek Sollenberger    SkDebugf("Cache miss %%: %f\n", (fTotalRequests > 0)
37e2022cc36e47b9f0d219eb5cd24be61772c28d3bDerek Sollenberger                                    ? (float)fCacheMisses/(float)fTotalRequests : 0.0f);
38096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger    SkDebugf("---------------------\n");
39096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger#endif
4080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
4180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
4280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruvoid GrGpuGL::ProgramCache::abandon() {
4380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    for (int i = 0; i < fCount; ++i) {
4480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        GrAssert(NULL != fEntries[i].fProgram.get());
4580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        fEntries[i].fProgram->abandon();
4680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        fEntries[i].fProgram.reset(NULL);
4780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    }
4880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    fCount = 0;
4980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
5080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
517839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek SollenbergerGrGLProgram* GrGpuGL::ProgramCache::getProgram(const GrGLProgramDesc& desc,
52363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger                                               const GrEffectStage* stages[]) {
5380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    Entry newEntry;
5480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    newEntry.fKey.setKeyData(desc.asKey());
55096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger#ifdef PROGRAM_CACHE_STATS
56096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger    ++fTotalRequests;
57096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger#endif
5880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
5980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    Entry* entry = fHashCache.find(newEntry.fKey);
6080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    if (NULL == entry) {
61096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger#ifdef PROGRAM_CACHE_STATS
62096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger        ++fCacheMisses;
63096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger#endif
6480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        newEntry.fProgram.reset(GrGLProgram::Create(fGL, desc, stages));
6580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        if (NULL == newEntry.fProgram.get()) {
6680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            return NULL;
6780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        }
6880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        if (fCount < kMaxEntries) {
6980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            entry = fEntries + fCount;
7080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            ++fCount;
7180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        } else {
7280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            GrAssert(kMaxEntries == fCount);
7380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            entry = fEntries;
7480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            for (int i = 1; i < kMaxEntries; ++i) {
7580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                if (fEntries[i].fLRUStamp < entry->fLRUStamp) {
7680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                    entry = fEntries + i;
7780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                }
7880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            }
7980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            fHashCache.remove(entry->fKey, entry);
8080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        }
8180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        *entry = newEntry;
8280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        fHashCache.insert(entry->fKey, entry);
8380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    }
8480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
8580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    entry->fLRUStamp = fCurrLRUStamp;
8680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    if (GR_UINT32_MAX == fCurrLRUStamp) {
8780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        // wrap around! just trash our LRU, one time hit.
8880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        for (int i = 0; i < fCount; ++i) {
8980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            fEntries[i].fLRUStamp = 0;
9080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        }
9180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    }
9280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    ++fCurrLRUStamp;
9380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    return entry->fProgram;
9480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
9580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
9680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru////////////////////////////////////////////////////////////////////////////////
9780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
9880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruvoid GrGpuGL::abandonResources(){
9980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    INHERITED::abandonResources();
10080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    fProgramCache->abandon();
10180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    fHWProgramID = 0;
10280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
10380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
10480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru////////////////////////////////////////////////////////////////////////////////
10580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
10680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#define GL_CALL(X) GR_GL_CALL(this->glInterface(), X)
10780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
108096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenbergervoid GrGpuGL::flushPathStencilMatrix() {
109096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger    const SkMatrix& viewMatrix = this->getDrawState().getViewMatrix();
110096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger    const GrRenderTarget* rt = this->getDrawState().getRenderTarget();
111096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger    SkISize size;
112096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger    size.set(rt->width(), rt->height());
113363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger    const SkMatrix& vm = this->getDrawState().getViewMatrix();
11480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
115096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger    if (fHWPathStencilMatrixState.fRenderTargetOrigin != rt->origin() ||
116096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger        fHWPathStencilMatrixState.fViewMatrix.cheapEqualTo(viewMatrix) ||
117096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger        fHWPathStencilMatrixState.fRenderTargetSize!= size) {
118096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger        // rescale the coords from skia's "device" coords to GL's normalized coords,
119096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger        // and perform a y-flip if required.
120096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger        SkMatrix m;
121096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger        if (kBottomLeft_GrSurfaceOrigin == rt->origin()) {
122363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger            m.setScale(SkIntToScalar(2) / rt->width(), SkIntToScalar(-2) / rt->height());
123363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger            m.postTranslate(-SK_Scalar1, SK_Scalar1);
124096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger        } else {
125096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger            m.setScale(SkIntToScalar(2) / rt->width(), SkIntToScalar(2) / rt->height());
126096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger            m.postTranslate(-SK_Scalar1, -SK_Scalar1);
12780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        }
128096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger        m.preConcat(vm);
129096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger
130096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger        // GL wants a column-major 4x4.
131096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger        GrGLfloat mv[]  = {
132096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger            // col 0
133363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger            SkScalarToFloat(m[SkMatrix::kMScaleX]),
134363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger            SkScalarToFloat(m[SkMatrix::kMSkewY]),
135096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger            0,
136363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger            SkScalarToFloat(m[SkMatrix::kMPersp0]),
137096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger
138096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger            // col 1
139363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger            SkScalarToFloat(m[SkMatrix::kMSkewX]),
140363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger            SkScalarToFloat(m[SkMatrix::kMScaleY]),
141096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger            0,
142363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger            SkScalarToFloat(m[SkMatrix::kMPersp1]),
143096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger
144096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger            // col 2
145096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger            0, 0, 0, 0,
146096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger
147096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger            // col3
148363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger            SkScalarToFloat(m[SkMatrix::kMTransX]),
149363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger            SkScalarToFloat(m[SkMatrix::kMTransY]),
150096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger            0.0f,
151363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger            SkScalarToFloat(m[SkMatrix::kMPersp2])
15280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        };
153096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger        GL_CALL(MatrixMode(GR_GL_PROJECTION));
154096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger        GL_CALL(LoadMatrixf(mv));
155096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger        fHWPathStencilMatrixState.fViewMatrix = vm;
156096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger        fHWPathStencilMatrixState.fRenderTargetSize = size;
157096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger        fHWPathStencilMatrixState.fRenderTargetOrigin = rt->origin();
15880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    }
15980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
16080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
1617839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenbergerbool GrGpuGL::flushGraphicsState(DrawType type, const GrDeviceCoordTexture* dstCopy) {
16280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    const GrDrawState& drawState = this->getDrawState();
16380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
164096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger    // GrGpu::setupClipAndFlushState should have already checked this and bailed if not true.
16580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    GrAssert(NULL != drawState.getRenderTarget());
16680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
167096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger    if (kStencilPath_DrawType == type) {
168096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger        this->flushPathStencilMatrix();
169096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger    } else {
17080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        this->flushMiscFixedFunctionState();
17180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
17280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        GrBlendCoeff srcCoeff;
17380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        GrBlendCoeff dstCoeff;
174096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger        GrDrawState::BlendOptFlags blendOpts = drawState.getBlendOpts(false, &srcCoeff, &dstCoeff);
175096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger        if (GrDrawState::kSkipDraw_BlendOptFlag & blendOpts) {
17680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            return false;
17780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        }
17880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
179363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger        const GrEffectStage* stages[GrDrawState::kNumStages];
180363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger        for (int i = 0; i < GrDrawState::kNumStages; ++i) {
181363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger            stages[i] = drawState.isStageEnabled(i) ? &drawState.getStage(i) : NULL;
182363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger        }
1837839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        GrGLProgramDesc desc;
1847839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        GrGLProgramDesc::Build(this->getDrawState(),
185096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger                               kDrawPoints_DrawType == type,
186096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger                               blendOpts,
187096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger                               srcCoeff,
188096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger                               dstCoeff,
189096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger                               this,
1907839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger                               dstCopy,
191096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger                               &desc);
19280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
193363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger        fCurrentProgram.reset(fProgramCache->getProgram(desc, stages));
19480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        if (NULL == fCurrentProgram.get()) {
19580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            GrAssert(!"Failed to create program!");
19680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            return false;
19780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        }
19880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        fCurrentProgram.get()->ref();
19980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
200096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger        GrGLuint programID = fCurrentProgram->programID();
201096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger        if (fHWProgramID != programID) {
202096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger            GL_CALL(UseProgram(programID));
203096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger            fHWProgramID = programID;
20480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        }
205096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger
20680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        fCurrentProgram->overrideBlend(&srcCoeff, &dstCoeff);
20780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        this->flushBlend(kDrawLines_DrawType == type, srcCoeff, dstCoeff);
20880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
20980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        GrColor color;
21080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        GrColor coverage;
211096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger        if (blendOpts & GrDrawState::kEmitTransBlack_BlendOptFlag) {
21280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            color = 0;
21380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            coverage = 0;
214096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger        } else if (blendOpts & GrDrawState::kEmitCoverage_BlendOptFlag) {
21580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            color = 0xffffffff;
21680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            coverage = drawState.getCoverage();
21780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        } else {
21880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            color = drawState.getColor();
21980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            coverage = drawState.getCoverage();
22080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        }
2217839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger        fCurrentProgram->setData(this, color, coverage, dstCopy, &fSharedGLProgramState);
22280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    }
22380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    this->flushStencil(type);
22480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    this->flushScissor();
22580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    this->flushAAState(type);
22680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
22780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    GrIRect* devRect = NULL;
22880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    GrIRect devClipBounds;
22980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    if (drawState.isClipState()) {
230d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger        this->getClip()->getConservativeBounds(drawState.getRenderTarget(), &devClipBounds);
23180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        devRect = &devClipBounds;
23280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    }
23380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    // This must come after textures are flushed because a texture may need
23480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    // to be msaa-resolved (which will modify bound FBO state).
23580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    this->flushRenderTarget(devRect);
23680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
23780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    return true;
23880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
23980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
240096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenbergervoid GrGpuGL::setupGeometry(const DrawInfo& info, size_t* indexOffsetInBytes) {
24180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
242096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger    GrGLsizei stride = this->getDrawState().getVertexSize();
24380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
244096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger    size_t vertexOffsetInBytes = stride * info.startVertex();
24580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
246096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger    const GeometryPoolState& geoPoolState = this->getGeomPoolState();
24780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
248096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger    GrGLVertexBuffer* vbuf;
249096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger    switch (this->getGeomSrc().fVertexSrc) {
250096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger        case kBuffer_GeometrySrcType:
251096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger            vbuf = (GrGLVertexBuffer*) this->getGeomSrc().fVertexBuffer;
252096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger            break;
253096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger        case kArray_GeometrySrcType:
254096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger        case kReserved_GeometrySrcType:
255096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger            this->finalizeReservedVertices();
256096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger            vertexOffsetInBytes += geoPoolState.fPoolStartVertex * this->getGeomSrc().fVertexSize;
257096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger            vbuf = (GrGLVertexBuffer*) geoPoolState.fPoolVertexBuffer;
258096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger            break;
259096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger        default:
260096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger            vbuf = NULL; // suppress warning
261096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger            GrCrash("Unknown geometry src type!");
26280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    }
26380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
264096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger    GrAssert(NULL != vbuf);
265096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger    GrAssert(!vbuf->isLocked());
266096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger    vertexOffsetInBytes += vbuf->baseOffset();
267096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger
268096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger    GrGLIndexBuffer* ibuf = NULL;
269096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger    if (info.isIndexed()) {
270096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger        GrAssert(NULL != indexOffsetInBytes);
271096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger
272096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger        switch (this->getGeomSrc().fIndexSrc) {
273096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger        case kBuffer_GeometrySrcType:
274096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger            *indexOffsetInBytes = 0;
275096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger            ibuf = (GrGLIndexBuffer*)this->getGeomSrc().fIndexBuffer;
276096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger            break;
277096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger        case kArray_GeometrySrcType:
278096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger        case kReserved_GeometrySrcType:
279096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger            this->finalizeReservedIndices();
280096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger            *indexOffsetInBytes = geoPoolState.fPoolStartIndex * sizeof(GrGLushort);
281096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger            ibuf = (GrGLIndexBuffer*) geoPoolState.fPoolIndexBuffer;
282096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger            break;
283096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger        default:
284096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger            ibuf = NULL; // suppress warning
285096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger            GrCrash("Unknown geometry src type!");
28680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        }
28780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
288096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger        GrAssert(NULL != ibuf);
289096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger        GrAssert(!ibuf->isLocked());
290096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger        *indexOffsetInBytes += ibuf->baseOffset();
29180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    }
292096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger    GrGLAttribArrayState* attribState =
293096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger        fHWGeometryState.bindArrayAndBuffersToDraw(this, vbuf, ibuf);
294096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger
295096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger    uint32_t usedAttribArraysMask = 0;
296096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger    const GrVertexAttrib* vertexAttrib = this->getDrawState().getVertexAttribs();
297096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger    int vertexAttribCount = this->getDrawState().getVertexAttribCount();
298096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger    for (int vertexAttribIndex = 0; vertexAttribIndex < vertexAttribCount;
299096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger         ++vertexAttribIndex, ++vertexAttrib) {
300096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger
301096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger        usedAttribArraysMask |= (1 << vertexAttribIndex);
302096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger        GrVertexAttribType attribType = vertexAttrib->fType;
303096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger        attribState->set(this,
304096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger                         vertexAttribIndex,
305096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger                         vbuf,
3067839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger                         GrGLAttribTypeToLayout(attribType).fCount,
3077839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger                         GrGLAttribTypeToLayout(attribType).fType,
3087839ce1af63bf12fe7b3caa866970bbbb3afb13dDerek Sollenberger                         GrGLAttribTypeToLayout(attribType).fNormalized,
309096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger                         stride,
310096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger                         reinterpret_cast<GrGLvoid*>(
311096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger                         vertexOffsetInBytes + vertexAttrib->fOffset));
31280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    }
31380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
314096defe64d408e54474fe19f418c95bf1a554fc7Derek Sollenberger    attribState->disableUnusedAttribArrays(this, usedAttribArraysMask);
31580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
316