GrGLProgram.h revision b930cc3dcb0645a8ce0689c5feb9c0defda57f28
1ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com/* 2ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * Copyright 2011 Google Inc. 3ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * 4ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * Use of this source code is governed by a BSD-style license that can be 5ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * found in the LICENSE file. 6f93e717c7f7ca679a80acbfda6a34013ae1e2b8djunov@google.com */ 7f93e717c7f7ca679a80acbfda6a34013ae1e2b8djunov@google.com 8ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com 9f93e717c7f7ca679a80acbfda6a34013ae1e2b8djunov@google.com#ifndef GrGLProgram_DEFINED 10f93e717c7f7ca679a80acbfda6a34013ae1e2b8djunov@google.com#define GrGLProgram_DEFINED 11f93e717c7f7ca679a80acbfda6a34013ae1e2b8djunov@google.com 12d8f856c32b679d9f5a9926feac005e2c0186f83ftomhudson@google.com#include "GrDrawState.h" 136177e6999d23a4268ffd98dedfb1da00e272a89brobertphillips@google.com#include "GrGLContext.h" 1431ec7985f2b52a0cab4aa714a613b918cf663c08bsalomon@google.com#include "GrGLProgramDesc.h" 155a02cb48fdff04dc274d4cb1af8c4dc65a503438commit-bot@chromium.org#include "GrGLShaderBuilder.h" 16086e5354fe7ae60e69c42bdfbc3d03bd8559b44ftomhudson@google.com#include "GrGLSL.h" 17890e3b58e78c0825820f75f1f0c5a5d71e855aa6bsalomon@google.com#include "GrGLTexture.h" 18dbbc4e2da93cef5c0cfb0b3c92ff6c2c80f6e67absalomon@google.com#include "GrGLUniformManager.h" 19f93e717c7f7ca679a80acbfda6a34013ae1e2b8djunov@google.com 20f0a104e6f16dc095286d32f1e104894ae0b2b19fbsalomon@google.com#include "SkString.h" 2197c88c255cff3dbb8343c5d090526fdbedad6dd6Scroggo#include "SkXfermode.h" 2297c88c255cff3dbb8343c5d090526fdbedad6dd6Scroggo 23f93e717c7f7ca679a80acbfda6a34013ae1e2b8djunov@google.comclass GrBinHashKeyBuilder; 24d698f77c13d97c61109b861eac4d25b14a5de935bsalomon@google.comclass GrGLEffect; 253390b9ac9ad69a6e772c2b957d75d19611239025commit-bot@chromium.orgclass GrGLProgramEffects; 26f9ad8867f2bcd8563862b0a5a90b473ad020d465tomhudson@google.comclass GrGLShaderBuilder; 27f93e717c7f7ca679a80acbfda6a34013ae1e2b8djunov@google.com 28f93e717c7f7ca679a80acbfda6a34013ae1e2b8djunov@google.com/** 29f93e717c7f7ca679a80acbfda6a34013ae1e2b8djunov@google.com * This class manages a GPU program and records per-program information. 30f93e717c7f7ca679a80acbfda6a34013ae1e2b8djunov@google.com * We can specify the attribute locations so that they are constant 31f93e717c7f7ca679a80acbfda6a34013ae1e2b8djunov@google.com * across our shaders. But the driver determines the uniform locations 32f93e717c7f7ca679a80acbfda6a34013ae1e2b8djunov@google.com * at link time. We don't need to remember the sampler uniform location 33f93e717c7f7ca679a80acbfda6a34013ae1e2b8djunov@google.com * because we will bind a texture slot to it and never change it 34f93e717c7f7ca679a80acbfda6a34013ae1e2b8djunov@google.com * Uniforms are program-local so we can't rely on fHWState to hold the 35f93e717c7f7ca679a80acbfda6a34013ae1e2b8djunov@google.com * previous uniform state after a program change. 36f93e717c7f7ca679a80acbfda6a34013ae1e2b8djunov@google.com */ 37a4de8c257ea0be8ff7081f645249b6afe5c48e7ecommit-bot@chromium.orgclass GrGLProgram : public SkRefCnt { 38f93e717c7f7ca679a80acbfda6a34013ae1e2b8djunov@google.compublic: 399ba4fa6f0fb8ef496d81ccac36e780aa806fea83bsalomon@google.com SK_DECLARE_INST_COUNT(GrGLProgram) 404fa6694c587b3830932429766c99d08c8dd9b723bsalomon@google.com 419188a15f846ae79892c332aed2a72ee38116bdc6commit-bot@chromium.org static GrGLProgram* Create(GrGpuGL* gpu, 4231ec7985f2b52a0cab4aa714a613b918cf663c08bsalomon@google.com const GrGLProgramDesc& desc, 432c84aa35988c661b3e5513c8ba9b3959832ff288bsalomon@google.com const GrEffectStage* colorStages[], 442c84aa35988c661b3e5513c8ba9b3959832ff288bsalomon@google.com const GrEffectStage* coverageStages[]); 45ecb60aad5c6fe5b1dbcfc86ac00bfc9326103c8dbsalomon@google.com 469ba4fa6f0fb8ef496d81ccac36e780aa806fea83bsalomon@google.com virtual ~GrGLProgram(); 47f93e717c7f7ca679a80acbfda6a34013ae1e2b8djunov@google.com 4834cccde630fc618649b9737bee464203d042bfbbbsalomon@google.com /** 4934cccde630fc618649b9737bee464203d042bfbbbsalomon@google.com * Call to abandon GL objects owned by this program. 5034cccde630fc618649b9737bee464203d042bfbbbsalomon@google.com */ 51ecb60aad5c6fe5b1dbcfc86ac00bfc9326103c8dbsalomon@google.com void abandon(); 52ecb60aad5c6fe5b1dbcfc86ac00bfc9326103c8dbsalomon@google.com 53f93e717c7f7ca679a80acbfda6a34013ae1e2b8djunov@google.com /** 542db3ded335fdb6697623bece61cabc307a414770bsalomon@google.com * The shader may modify the blend coefficients. Params are in/out. 55f93e717c7f7ca679a80acbfda6a34013ae1e2b8djunov@google.com */ 56ecb60aad5c6fe5b1dbcfc86ac00bfc9326103c8dbsalomon@google.com void overrideBlend(GrBlendCoeff* srcCoeff, GrBlendCoeff* dstCoeff) const; 57f93e717c7f7ca679a80acbfda6a34013ae1e2b8djunov@google.com 5831ec7985f2b52a0cab4aa714a613b918cf663c08bsalomon@google.com const GrGLProgramDesc& getDesc() { return fDesc; } 599ba4fa6f0fb8ef496d81ccac36e780aa806fea83bsalomon@google.com 60271cffc77bd2fcb3458559e509634442517ca1e9bsalomon@google.com /** 616a51dcbf81cff6d92996ab3f4c7457478e441896bsalomon@google.com * Gets the GL program ID for this program. 626a51dcbf81cff6d92996ab3f4c7457478e441896bsalomon@google.com */ 636a51dcbf81cff6d92996ab3f4c7457478e441896bsalomon@google.com GrGLuint programID() const { return fProgramID; } 646a51dcbf81cff6d92996ab3f4c7457478e441896bsalomon@google.com 656b30e457409f37c91c301cd82040e733e2930286commit-bot@chromium.org bool hasVertexShader() const { return fHasVertexShader; } 666b30e457409f37c91c301cd82040e733e2930286commit-bot@chromium.org 676a51dcbf81cff6d92996ab3f4c7457478e441896bsalomon@google.com /** 68054ae99d93711c26e40682a0e3a03a47ea605c53jvanverth@google.com * Some GL state that is relevant to programs is not stored per-program. In particular color 6905a2ee052c9ef4c781b7b590b00b3d2da3b3449askia.committer@gmail.com * and coverage attributes can be global state. This struct is read and updated by 7005a2ee052c9ef4c781b7b590b00b3d2da3b3449askia.committer@gmail.com * GrGLProgram::setColor and GrGLProgram::setCoverage to allow us to avoid setting this state 71054ae99d93711c26e40682a0e3a03a47ea605c53jvanverth@google.com * redundantly. 7291207482c9398944fc997aeb99ed5f8674be58cbbsalomon@google.com */ 7391207482c9398944fc997aeb99ed5f8674be58cbbsalomon@google.com struct SharedGLState { 7491207482c9398944fc997aeb99ed5f8674be58cbbsalomon@google.com GrColor fConstAttribColor; 75054ae99d93711c26e40682a0e3a03a47ea605c53jvanverth@google.com int fConstAttribColorIndex; 7691207482c9398944fc997aeb99ed5f8674be58cbbsalomon@google.com GrColor fConstAttribCoverage; 77054ae99d93711c26e40682a0e3a03a47ea605c53jvanverth@google.com int fConstAttribCoverageIndex; 7891207482c9398944fc997aeb99ed5f8674be58cbbsalomon@google.com 7991207482c9398944fc997aeb99ed5f8674be58cbbsalomon@google.com SharedGLState() { this->invalidate(); } 8091207482c9398944fc997aeb99ed5f8674be58cbbsalomon@google.com void invalidate() { 8191207482c9398944fc997aeb99ed5f8674be58cbbsalomon@google.com fConstAttribColor = GrColor_ILLEGAL; 82054ae99d93711c26e40682a0e3a03a47ea605c53jvanverth@google.com fConstAttribColorIndex = -1; 8391207482c9398944fc997aeb99ed5f8674be58cbbsalomon@google.com fConstAttribCoverage = GrColor_ILLEGAL; 84054ae99d93711c26e40682a0e3a03a47ea605c53jvanverth@google.com fConstAttribCoverageIndex = -1; 8591207482c9398944fc997aeb99ed5f8674be58cbbsalomon@google.com } 8691207482c9398944fc997aeb99ed5f8674be58cbbsalomon@google.com }; 8791207482c9398944fc997aeb99ed5f8674be58cbbsalomon@google.com 8891207482c9398944fc997aeb99ed5f8674be58cbbsalomon@google.com /** 896a51dcbf81cff6d92996ab3f4c7457478e441896bsalomon@google.com * The GrDrawState's view matrix along with the aspects of the render target determine the 906a51dcbf81cff6d92996ab3f4c7457478e441896bsalomon@google.com * matrix sent to GL. The size of the render target affects the GL matrix because we must 916a51dcbf81cff6d92996ab3f4c7457478e441896bsalomon@google.com * convert from Skia device coords to GL's normalized coords. Also the origin of the render 926a51dcbf81cff6d92996ab3f4c7457478e441896bsalomon@google.com * target may require us to perform a mirror-flip. 936a51dcbf81cff6d92996ab3f4c7457478e441896bsalomon@google.com */ 946a51dcbf81cff6d92996ab3f4c7457478e441896bsalomon@google.com struct MatrixState { 956a51dcbf81cff6d92996ab3f4c7457478e441896bsalomon@google.com SkMatrix fViewMatrix; 966a51dcbf81cff6d92996ab3f4c7457478e441896bsalomon@google.com SkISize fRenderTargetSize; 976a51dcbf81cff6d92996ab3f4c7457478e441896bsalomon@google.com GrSurfaceOrigin fRenderTargetOrigin; 986a51dcbf81cff6d92996ab3f4c7457478e441896bsalomon@google.com 996a51dcbf81cff6d92996ab3f4c7457478e441896bsalomon@google.com MatrixState() { this->invalidate(); } 1006a51dcbf81cff6d92996ab3f4c7457478e441896bsalomon@google.com void invalidate() { 1016a51dcbf81cff6d92996ab3f4c7457478e441896bsalomon@google.com fViewMatrix = SkMatrix::InvalidMatrix(); 10245a412ee365694c61b50f6177382b509d1e2462bbsalomon@google.com fRenderTargetSize.fWidth = -1; 10345a412ee365694c61b50f6177382b509d1e2462bbsalomon@google.com fRenderTargetSize.fHeight = -1; 1046a51dcbf81cff6d92996ab3f4c7457478e441896bsalomon@google.com fRenderTargetOrigin = (GrSurfaceOrigin) -1; 1056a51dcbf81cff6d92996ab3f4c7457478e441896bsalomon@google.com } 106215a682d2d561be69b7a28eb76a98849ad03cbc0commit-bot@chromium.org template<int Size> void getGLMatrix(GrGLfloat* destMatrix) { 107215a682d2d561be69b7a28eb76a98849ad03cbc0commit-bot@chromium.org SkMatrix combined; 108215a682d2d561be69b7a28eb76a98849ad03cbc0commit-bot@chromium.org if (kBottomLeft_GrSurfaceOrigin == fRenderTargetOrigin) { 109215a682d2d561be69b7a28eb76a98849ad03cbc0commit-bot@chromium.org combined.setAll(SkIntToScalar(2) / fRenderTargetSize.fWidth, 0, -SK_Scalar1, 110215a682d2d561be69b7a28eb76a98849ad03cbc0commit-bot@chromium.org 0, -SkIntToScalar(2) / fRenderTargetSize.fHeight, SK_Scalar1, 111215a682d2d561be69b7a28eb76a98849ad03cbc0commit-bot@chromium.org 0, 0, SkMatrix::I()[8]); 112215a682d2d561be69b7a28eb76a98849ad03cbc0commit-bot@chromium.org } else { 113215a682d2d561be69b7a28eb76a98849ad03cbc0commit-bot@chromium.org combined.setAll(SkIntToScalar(2) / fRenderTargetSize.fWidth, 0, -SK_Scalar1, 114215a682d2d561be69b7a28eb76a98849ad03cbc0commit-bot@chromium.org 0, SkIntToScalar(2) / fRenderTargetSize.fHeight, -SK_Scalar1, 115215a682d2d561be69b7a28eb76a98849ad03cbc0commit-bot@chromium.org 0, 0, SkMatrix::I()[8]); 116215a682d2d561be69b7a28eb76a98849ad03cbc0commit-bot@chromium.org } 117b930cc3dcb0645a8ce0689c5feb9c0defda57f28commit-bot@chromium.org combined.preConcat(fViewMatrix); 118215a682d2d561be69b7a28eb76a98849ad03cbc0commit-bot@chromium.org GrGLGetMatrix<Size>(destMatrix, combined); 119215a682d2d561be69b7a28eb76a98849ad03cbc0commit-bot@chromium.org } 1206a51dcbf81cff6d92996ab3f4c7457478e441896bsalomon@google.com }; 1216a51dcbf81cff6d92996ab3f4c7457478e441896bsalomon@google.com 1226a51dcbf81cff6d92996ab3f4c7457478e441896bsalomon@google.com /** 12334cccde630fc618649b9737bee464203d042bfbbbsalomon@google.com * This function uploads uniforms and calls each GrGLEffect's setData. It is called before a 12434cccde630fc618649b9737bee464203d042bfbbbsalomon@google.com * draw occurs using the program after the program has already been bound. It also uses the 1252c84aa35988c661b3e5513c8ba9b3959832ff288bsalomon@google.com * GrGpuGL object to bind the textures required by the GrGLEffects. The color and coverage 1262c84aa35988c661b3e5513c8ba9b3959832ff288bsalomon@google.com * stages come from GrGLProgramDesc::Build(). 1274285accf5af574e6c826d5d09f0359c6149fd717bsalomon@google.com */ 1289188a15f846ae79892c332aed2a72ee38116bdc6commit-bot@chromium.org void setData(GrDrawState::BlendOptFlags, 1292c84aa35988c661b3e5513c8ba9b3959832ff288bsalomon@google.com const GrEffectStage* colorStages[], 1302c84aa35988c661b3e5513c8ba9b3959832ff288bsalomon@google.com const GrEffectStage* coverageStages[], 13126e18b593ab65e4d92dfbce92579d8bc180d4c2cbsalomon@google.com const GrDeviceCoordTexture* dstCopy, // can be NULL 13226e18b593ab65e4d92dfbce92579d8bc180d4c2cbsalomon@google.com SharedGLState*); 1339196130af83782fcac4334117142475a837dd74dbsalomon@google.com 1342a2e3ef5b84de3347aedaf1f7dd93cfcdb53d7f1tomhudson@google.comprivate: 135dbbc4e2da93cef5c0cfb0b3c92ff6c2c80f6e67absalomon@google.com typedef GrGLUniformManager::UniformHandle UniformHandle; 136dbbc4e2da93cef5c0cfb0b3c92ff6c2c80f6e67absalomon@google.com 137804e9941ebd6217c592ecee2b5a5d1cbeaea1c42bsalomon@google.com // handles for uniforms (aside from per-effect samplers) 13834cccde630fc618649b9737bee464203d042bfbbbsalomon@google.com struct UniformHandles { 13934cccde630fc618649b9737bee464203d042bfbbbsalomon@google.com UniformHandle fViewMatrixUni; 14034cccde630fc618649b9737bee464203d042bfbbbsalomon@google.com UniformHandle fColorUni; 14134cccde630fc618649b9737bee464203d042bfbbbsalomon@google.com UniformHandle fCoverageUni; 14226e18b593ab65e4d92dfbce92579d8bc180d4c2cbsalomon@google.com 143706f66831a575bdc2b1ab1331b48b793cd487356bsalomon@google.com // We use the render target height to provide a y-down frag coord when specifying 144706f66831a575bdc2b1ab1331b48b793cd487356bsalomon@google.com // origin_upper_left is not supported. 14534cccde630fc618649b9737bee464203d042bfbbbsalomon@google.com UniformHandle fRTHeightUni; 14626e18b593ab65e4d92dfbce92579d8bc180d4c2cbsalomon@google.com 14726e18b593ab65e4d92dfbce92579d8bc180d4c2cbsalomon@google.com // Uniforms for computing texture coords to do the dst-copy lookup 14826e18b593ab65e4d92dfbce92579d8bc180d4c2cbsalomon@google.com UniformHandle fDstCopyTopLeftUni; 14926e18b593ab65e4d92dfbce92579d8bc180d4c2cbsalomon@google.com UniformHandle fDstCopyScaleUni; 15026e18b593ab65e4d92dfbce92579d8bc180d4c2cbsalomon@google.com UniformHandle fDstCopySamplerUni; 151f93e717c7f7ca679a80acbfda6a34013ae1e2b8djunov@google.com }; 152f93e717c7f7ca679a80acbfda6a34013ae1e2b8djunov@google.com 1539188a15f846ae79892c332aed2a72ee38116bdc6commit-bot@chromium.org GrGLProgram(GrGpuGL* gpu, 1542c84aa35988c661b3e5513c8ba9b3959832ff288bsalomon@google.com const GrGLProgramDesc& desc, 1552c84aa35988c661b3e5513c8ba9b3959832ff288bsalomon@google.com const GrEffectStage* colorStages[], 1562c84aa35988c661b3e5513c8ba9b3959832ff288bsalomon@google.com const GrEffectStage* coverageStages[]); 1572c84aa35988c661b3e5513c8ba9b3959832ff288bsalomon@google.com 1582c84aa35988c661b3e5513c8ba9b3959832ff288bsalomon@google.com bool succeeded() const { return 0 != fProgramID; } 1592c84aa35988c661b3e5513c8ba9b3959832ff288bsalomon@google.com 1602c84aa35988c661b3e5513c8ba9b3959832ff288bsalomon@google.com /** 1612c84aa35988c661b3e5513c8ba9b3959832ff288bsalomon@google.com * This is the heavy initialization routine for building a GLProgram. colorStages and 1622c84aa35988c661b3e5513c8ba9b3959832ff288bsalomon@google.com * coverageStages correspond to the output of GrGLProgramDesc::Build(). 1632c84aa35988c661b3e5513c8ba9b3959832ff288bsalomon@google.com */ 1646b30e457409f37c91c301cd82040e733e2930286commit-bot@chromium.org bool genProgram(GrGLShaderBuilder* builder, 1656b30e457409f37c91c301cd82040e733e2930286commit-bot@chromium.org const GrEffectStage* colorStages[], 1666b30e457409f37c91c301cd82040e733e2930286commit-bot@chromium.org const GrEffectStage* coverageStages[]); 1672c84aa35988c661b3e5513c8ba9b3959832ff288bsalomon@google.com 1682c84aa35988c661b3e5513c8ba9b3959832ff288bsalomon@google.com // Sets the texture units for samplers 1692c84aa35988c661b3e5513c8ba9b3959832ff288bsalomon@google.com void initSamplerUniforms(); 1702c84aa35988c661b3e5513c8ba9b3959832ff288bsalomon@google.com 1712c84aa35988c661b3e5513c8ba9b3959832ff288bsalomon@google.com // Helper for setData(). Makes GL calls to specify the initial color when there is not 1722c84aa35988c661b3e5513c8ba9b3959832ff288bsalomon@google.com // per-vertex colors. 1732c84aa35988c661b3e5513c8ba9b3959832ff288bsalomon@google.com void setColor(const GrDrawState&, GrColor color, SharedGLState*); 1742c84aa35988c661b3e5513c8ba9b3959832ff288bsalomon@google.com 1752c84aa35988c661b3e5513c8ba9b3959832ff288bsalomon@google.com // Helper for setData(). Makes GL calls to specify the initial coverage when there is not 1762c84aa35988c661b3e5513c8ba9b3959832ff288bsalomon@google.com // per-vertex coverages. 1772c84aa35988c661b3e5513c8ba9b3959832ff288bsalomon@google.com void setCoverage(const GrDrawState&, GrColor coverage, SharedGLState*); 1782c84aa35988c661b3e5513c8ba9b3959832ff288bsalomon@google.com 1792c84aa35988c661b3e5513c8ba9b3959832ff288bsalomon@google.com // Helper for setData() that sets the view matrix and loads the render target height uniform 1802c84aa35988c661b3e5513c8ba9b3959832ff288bsalomon@google.com void setMatrixAndRenderTargetHeight(const GrDrawState&); 1812c84aa35988c661b3e5513c8ba9b3959832ff288bsalomon@google.com 182410552a73d59611901033b2bc5147cc6ade0207ccommit-bot@chromium.org // GL program ID 18334cccde630fc618649b9737bee464203d042bfbbbsalomon@google.com GrGLuint fProgramID; 1849ba4fa6f0fb8ef496d81ccac36e780aa806fea83bsalomon@google.com 18534cccde630fc618649b9737bee464203d042bfbbbsalomon@google.com // these reflect the current values of uniforms (GL uniform values travel with program) 1863390b9ac9ad69a6e772c2b957d75d19611239025commit-bot@chromium.org MatrixState fMatrixState; 1873390b9ac9ad69a6e772c2b957d75d19611239025commit-bot@chromium.org GrColor fColor; 1883390b9ac9ad69a6e772c2b957d75d19611239025commit-bot@chromium.org GrColor fCoverage; 1893390b9ac9ad69a6e772c2b957d75d19611239025commit-bot@chromium.org int fDstCopyTexUnit; 1909ba4fa6f0fb8ef496d81ccac36e780aa806fea83bsalomon@google.com 1913390b9ac9ad69a6e772c2b957d75d19611239025commit-bot@chromium.org SkAutoTDelete<GrGLProgramEffects> fColorEffects; 1923390b9ac9ad69a6e772c2b957d75d19611239025commit-bot@chromium.org SkAutoTDelete<GrGLProgramEffects> fCoverageEffects; 1939ba4fa6f0fb8ef496d81ccac36e780aa806fea83bsalomon@google.com 1943390b9ac9ad69a6e772c2b957d75d19611239025commit-bot@chromium.org GrGLProgramDesc fDesc; 1953390b9ac9ad69a6e772c2b957d75d19611239025commit-bot@chromium.org GrGpuGL* fGpu; 1969ba4fa6f0fb8ef496d81ccac36e780aa806fea83bsalomon@google.com 1973390b9ac9ad69a6e772c2b957d75d19611239025commit-bot@chromium.org GrGLUniformManager fUniformManager; 1983390b9ac9ad69a6e772c2b957d75d19611239025commit-bot@chromium.org UniformHandles fUniformHandles; 199dbbc4e2da93cef5c0cfb0b3c92ff6c2c80f6e67absalomon@google.com 2006b30e457409f37c91c301cd82040e733e2930286commit-bot@chromium.org bool fHasVertexShader; 2016b30e457409f37c91c301cd82040e733e2930286commit-bot@chromium.org int fNumTexCoordSets; 2026b30e457409f37c91c301cd82040e733e2930286commit-bot@chromium.org 203a4de8c257ea0be8ff7081f645249b6afe5c48e7ecommit-bot@chromium.org typedef SkRefCnt INHERITED; 204f93e717c7f7ca679a80acbfda6a34013ae1e2b8djunov@google.com}; 205f93e717c7f7ca679a80acbfda6a34013ae1e2b8djunov@google.com 206f93e717c7f7ca679a80acbfda6a34013ae1e2b8djunov@google.com#endif 207