Пример #1
0
void GrDrawTarget::setBlendFunc(GrBlendCoeff srcCoeff,
                                GrBlendCoeff dstCoeff) {
    fCurrDrawState.fSrcBlend = srcCoeff;
    fCurrDrawState.fDstBlend = dstCoeff;
#if GR_DEBUG
    switch (dstCoeff) {
    case kDC_BlendCoeff:
    case kIDC_BlendCoeff:
    case kDA_BlendCoeff:
    case kIDA_BlendCoeff:
        GrPrintf("Unexpected dst blend coeff. Won't work correctly with"
                 "coverage stages.\n");
        break;
    default:
        break;
    }
    switch (srcCoeff) {
    case kSC_BlendCoeff:
    case kISC_BlendCoeff:
    case kSA_BlendCoeff:
    case kISA_BlendCoeff:
        GrPrintf("Unexpected src blend coeff. Won't work correctly with"
                 "coverage stages.\n");
        break;
    default:
        break;
    }
#endif
}
Пример #2
0
GrGLuint GrGLProgram::CompileShader(GrGLenum type,
                                      int stringCnt,
                                      const char** strings,
                                      int* stringLengths) {
    GrGLuint shader = GR_GL(CreateShader(type));
    if (0 == shader) {
        return 0;
    }

    GrGLint compiled = GR_GL_INIT_ZERO;
    GR_GL(ShaderSource(shader, stringCnt, strings, stringLengths));
    GR_GL(CompileShader(shader));
    GR_GL(GetShaderiv(shader, GR_GL_COMPILE_STATUS, &compiled));

    if (!compiled) {
        GrGLint infoLen = GR_GL_INIT_ZERO;
        GR_GL(GetShaderiv(shader, GR_GL_INFO_LOG_LENGTH, &infoLen));
        GrAutoMalloc log(sizeof(char)*(infoLen+1)); // outside if for debugger
        if (infoLen > 0) {
            GR_GL(GetShaderInfoLog(shader, infoLen+1, NULL, (char*)log.get()));
            for (int i = 0; i < stringCnt; ++i) {
                if (NULL == stringLengths || stringLengths[i] < 0) {
                    GrPrintf(strings[i]);
                } else {
                    GrPrintf("%.*s", stringLengths[i], strings[i]);
                }
            }
            GrPrintf("\n%s", log.get());
        }
        GrAssert(!"Shader compilation failed!");
        GR_GL(DeleteShader(shader));
        return 0;
    }
    return shader;
}
Пример #3
0
void GrGLCaps::print() const {
    for (int i = 0; i < fStencilFormats.count(); ++i) {
        GrPrintf("Stencil Format %d, stencil bits: %02d, total bits: %02d\n",
                 i,
                 fStencilFormats[i].fStencilBits,
                 fStencilFormats[i].fTotalBits);
    }

    GR_STATIC_ASSERT(0 == kNone_MSFBOType);
    GR_STATIC_ASSERT(1 == kDesktopARB_MSFBOType);
    GR_STATIC_ASSERT(2 == kDesktopEXT_MSFBOType);
    GR_STATIC_ASSERT(3 == kAppleES_MSFBOType);
    static const char* gMSFBOExtStr[] = {
        "None",
        "ARB",
        "EXT",
        "Apple",
    };
    GrPrintf("MSAA Type: %s\n", gMSFBOExtStr[fMSFBOType]);
    GrPrintf("Max FS Uniform Vectors: %d\n", fMaxFragmentUniformVectors);
    GrPrintf("Support RGBA8 Render Buffer: %s\n",
             (fRGBA8RenderbufferSupport ? "YES": "NO"));
    GrPrintf("BGRA is an internal format: %s\n",
             (fBGRAIsInternalFormat ? "YES": "NO"));
    GrPrintf("Support texture swizzle: %s\n",
             (fTextureSwizzleSupport ? "YES": "NO"));
    GrPrintf("Unpack Row length support: %s\n",
             (fUnpackRowLengthSupport ? "YES": "NO"));
    GrPrintf("Unpack Flip Y support: %s\n",
             (fUnpackFlipYSupport ? "YES": "NO"));
    GrPrintf("Pack Row length support: %s\n",
             (fPackRowLengthSupport ? "YES": "NO"));
    GrPrintf("Pack Flip Y support: %s\n",
             (fPackFlipYSupport ? "YES": "NO"));
}
Пример #4
0
// Compiles a GL shader and attaches it to a program. Returns the shader ID if
// successful, or 0 if not.
static GrGLuint attach_shader(const GrGLContext& glCtx,
                              GrGLuint programId,
                              GrGLenum type,
                              const SkString& shaderSrc) {
    const GrGLInterface* gli = glCtx.interface();

    GrGLuint shaderId;
    GR_GL_CALL_RET(gli, shaderId, CreateShader(type));
    if (0 == shaderId) {
        return 0;
    }

    const GrGLchar* sourceStr = shaderSrc.c_str();
    GrGLint sourceLength = static_cast<GrGLint>(shaderSrc.size());
    GR_GL_CALL(gli, ShaderSource(shaderId, 1, &sourceStr, &sourceLength));
    GR_GL_CALL(gli, CompileShader(shaderId));

    // Calling GetShaderiv in Chromium is quite expensive. Assume success in release builds.
    bool checkCompiled = !glCtx.isChromium();
#ifdef SK_DEBUG
    checkCompiled = true;
#endif
    if (checkCompiled) {
        GrGLint compiled = GR_GL_INIT_ZERO;
        GR_GL_CALL(gli, GetShaderiv(shaderId, GR_GL_COMPILE_STATUS, &compiled));

        if (!compiled) {
            GrGLint infoLen = GR_GL_INIT_ZERO;
            GR_GL_CALL(gli, GetShaderiv(shaderId, GR_GL_INFO_LOG_LENGTH, &infoLen));
            SkAutoMalloc log(sizeof(char)*(infoLen+1)); // outside if for debugger
            if (infoLen > 0) {
                // retrieve length even though we don't need it to workaround bug in Chromium cmd
                // buffer param validation.
                GrGLsizei length = GR_GL_INIT_ZERO;
                GR_GL_CALL(gli, GetShaderInfoLog(shaderId, infoLen+1,
                                                 &length, (char*)log.get()));
                GrPrintf(shaderSrc.c_str());
                GrPrintf("\n%s", log.get());
            }
            SkDEBUGFAIL("Shader compilation failed!");
            GR_GL_CALL(gli, DeleteShader(shaderId));
            return 0;
        }
    }

    TRACE_EVENT_INSTANT1(TRACE_DISABLED_BY_DEFAULT("skia.gpu"), "skia_gpu::GLShader",
                         TRACE_EVENT_SCOPE_THREAD, "shader", TRACE_STR_COPY(shaderSrc.c_str()));
    if (c_PrintShaders) {
        GrPrintf(shaderSrc.c_str());
        GrPrintf("\n");
    }

    // Attach the shader, but defer deletion until after we have linked the program.
    // This works around a bug in the Android emulator's GLES2 wrapper which
    // will immediately delete the shader object and free its memory even though it's
    // attached to a program, which then causes glLinkProgram to fail.
    GR_GL_CALL(gli, AttachShader(programId, shaderId));

    return shaderId;
}
Пример #5
0
// Compiles a GL shader, attaches it to a program, and releases the shader's reference.
// (That way there's no need to hang on to the GL shader id and delete it later.)
static bool attach_shader(const GrGLContext& glCtx,
                          GrGLuint programId,
                          GrGLenum type,
                          const SkString& shaderSrc) {
    const GrGLInterface* gli = glCtx.interface();

    GrGLuint shaderId;
    GR_GL_CALL_RET(gli, shaderId, CreateShader(type));
    if (0 == shaderId) {
        return false;
    }

    const GrGLchar* sourceStr = shaderSrc.c_str();
    GrGLint sourceLength = static_cast<GrGLint>(shaderSrc.size());
    GR_GL_CALL(gli, ShaderSource(shaderId, 1, &sourceStr, &sourceLength));
    GR_GL_CALL(gli, CompileShader(shaderId));

    // Calling GetShaderiv in Chromium is quite expensive. Assume success in release builds.
    bool checkCompiled = !glCtx.info().isChromium();
#ifdef SK_DEBUG
    checkCompiled = true;
#endif
    if (checkCompiled) {
        GrGLint compiled = GR_GL_INIT_ZERO;
        GR_GL_CALL(gli, GetShaderiv(shaderId, GR_GL_COMPILE_STATUS, &compiled));

        if (!compiled) {
            GrGLint infoLen = GR_GL_INIT_ZERO;
            GR_GL_CALL(gli, GetShaderiv(shaderId, GR_GL_INFO_LOG_LENGTH, &infoLen));
            SkAutoMalloc log(sizeof(char)*(infoLen+1)); // outside if for debugger
            if (infoLen > 0) {
                // retrieve length even though we don't need it to workaround bug in Chromium cmd
                // buffer param validation.
                GrGLsizei length = GR_GL_INIT_ZERO;
                GR_GL_CALL(gli, GetShaderInfoLog(shaderId, infoLen+1,
                                                 &length, (char*)log.get()));
                GrPrintf(shaderSrc.c_str());
                GrPrintf("\n%s", log.get());
            }
            SkDEBUGFAIL("Shader compilation failed!");
            GR_GL_CALL(gli, DeleteShader(shaderId));
            return false;
        }
    }
    if (c_PrintShaders) {
        GrPrintf(shaderSrc.c_str());
        GrPrintf("\n");
    }

    GR_GL_CALL(gli, AttachShader(programId, shaderId));
    GR_GL_CALL(gli, DeleteShader(shaderId));
    return true;
}
Пример #6
0
void GrGLCheckErr(const char* location, const char* call) {
    uint32_t err =  GrGLGetGLInterface()->fGetError();
    if (GR_GL_NO_ERROR != err) {
        GrPrintf("---- glGetError %x", err);
        if (NULL != location) {
            GrPrintf(" at\n\t%s", location);
        }
        if (NULL != call) {
            GrPrintf("\n\t\t%s", call);
        }
        GrPrintf("\n");
    }
}
Пример #7
0
void GrAARectRenderer::fillAARect(GrGpu* gpu,
                                  GrDrawTarget* target,
                                  const GrRect& devRect,
                                  bool useVertexCoverage) {
    GrVertexLayout layout = aa_rect_layout(useVertexCoverage);

    size_t vsize = GrDrawState::VertexSize(layout);

    GrDrawTarget::AutoReleaseGeometry geo(target, layout, 8, 0);
    if (!geo.succeeded()) {
        GrPrintf("Failed to get space for vertices!\n");
        return;
    }

    GrIndexBuffer* indexBuffer = this->aaFillRectIndexBuffer(gpu);
    if (NULL == indexBuffer) {
        GrPrintf("Failed to create index buffer!\n");
        return;
    }

    intptr_t verts = reinterpret_cast<intptr_t>(geo.vertices());

    GrPoint* fan0Pos = reinterpret_cast<GrPoint*>(verts);
    GrPoint* fan1Pos = reinterpret_cast<GrPoint*>(verts + 4 * vsize);

    set_inset_fan(fan0Pos, vsize, devRect, -SK_ScalarHalf, -SK_ScalarHalf);
    set_inset_fan(fan1Pos, vsize, devRect,  SK_ScalarHalf,  SK_ScalarHalf);

    verts += sizeof(GrPoint);
    for (int i = 0; i < 4; ++i) {
        *reinterpret_cast<GrColor*>(verts + i * vsize) = 0;
    }

    GrColor innerColor;
    if (useVertexCoverage) {
        innerColor = 0xffffffff;
    } else {
        innerColor = target->getDrawState().getColor();
    }

    verts += 4 * vsize;
    for (int i = 0; i < 4; ++i) {
        *reinterpret_cast<GrColor*>(verts + i * vsize) = innerColor;
    }

    target->setIndexSourceToBuffer(indexBuffer);
    target->drawIndexedInstances(kTriangles_GrPrimitiveType, 1,
                                 kVertsPerAAFillRect,
                                 kIndicesPerAAFillRect);
}
Пример #8
0
void GrGLCheckErr(const GrGLInterface* gl,
                  const char* location,
                  const char* call) {
    uint32_t err = GR_GL_GET_ERROR(gl);
    if (GR_GL_NO_ERROR != err) {
        GrPrintf("---- glGetError 0x%x(%s)", err, get_error_string(err));
        if (NULL != location) {
            GrPrintf(" at\n\t%s", location);
        }
        if (NULL != call) {
            GrPrintf("\n\t\t%s", call);
        }
        GrPrintf("\n");
    }
}
Пример #9
0
GrTexture* GrLockCachedBitmapTexture(GrContext* ctx,
                                     const SkBitmap& bitmap,
                                     const GrTextureParams* params) {
    GrTexture* result = NULL;

    if (!bitmap.isVolatile()) {
        // If the bitmap isn't changing try to find a cached copy first
        uint64_t key = bitmap.getGenerationID();
        key |= ((uint64_t) bitmap.pixelRefOffset()) << 32;

        GrTextureDesc desc;
        desc.fWidth = bitmap.width();
        desc.fHeight = bitmap.height();
        desc.fConfig = SkBitmapConfig2GrPixelConfig(bitmap.config());

        GrCacheData cacheData(key);

        result = ctx->findAndLockTexture(desc, cacheData, params);
        if (NULL == result) {
            result = sk_gr_create_bitmap_texture(ctx, key, params, bitmap);
        }
    } else {
        result = sk_gr_create_bitmap_texture(ctx, GrCacheData::kScratch_CacheID, params, bitmap);
    }
    if (NULL == result) {
        GrPrintf("---- failed to create texture for cache [%d %d]\n",
                    bitmap.width(), bitmap.height());
    }
    return result;
}
Пример #10
0
GrGpu* GrGpu::Create(GrBackend backend, GrBackendContext backendContext, GrContext* context) {

    const GrGLInterface* glInterface = NULL;
    SkAutoTUnref<const GrGLInterface> glInterfaceUnref;

    if (kOpenGL_GrBackend == backend) {
        glInterface = reinterpret_cast<const GrGLInterface*>(backendContext);
        if (NULL == glInterface) {
            glInterface = GrGLDefaultInterface();
            // By calling GrGLDefaultInterface we've taken a ref on the
            // returned object. We only want to hold that ref until after
            // the GrGpu is constructed and has taken ownership.
            glInterfaceUnref.reset(glInterface);
        }
        if (NULL == glInterface) {
#ifdef SK_DEBUG
            GrPrintf("No GL interface provided!\n");
#endif
            return NULL;
        }
        GrGLContext ctx(glInterface);
        if (ctx.isInitialized()) {
            return SkNEW_ARGS(GrGpuGL, (ctx, context));
        }
    }
    return NULL;
}
Пример #11
0
bool GrGLShaderBuilder::finish() {
    SkASSERT(0 == fOutput.fProgramID);
    GL_CALL_RET(fOutput.fProgramID, CreateProgram());
    if (!fOutput.fProgramID) {
        return false;
    }

    SkTDArray<GrGLuint> shadersToDelete;

    if (!this->compileAndAttachShaders(fOutput.fProgramID, &shadersToDelete)) {
        GL_CALL(DeleteProgram(fOutput.fProgramID));
        return false;
    }

    this->bindProgramLocations(fOutput.fProgramID);
    if (fUniformManager->isUsingBindUniform()) {
        fUniformManager->getUniformLocations(fOutput.fProgramID, fUniforms);
    }

    GL_CALL(LinkProgram(fOutput.fProgramID));

    // Calling GetProgramiv is expensive in Chromium. Assume success in release builds.
    bool checkLinked = !fGpu->ctxInfo().isChromium();
#ifdef SK_DEBUG
    checkLinked = true;
#endif
    if (checkLinked) {
        GrGLint linked = GR_GL_INIT_ZERO;
        GL_CALL(GetProgramiv(fOutput.fProgramID, GR_GL_LINK_STATUS, &linked));
        if (!linked) {
            GrGLint infoLen = GR_GL_INIT_ZERO;
            GL_CALL(GetProgramiv(fOutput.fProgramID, GR_GL_INFO_LOG_LENGTH, &infoLen));
            SkAutoMalloc log(sizeof(char)*(infoLen+1));  // outside if for debugger
            if (infoLen > 0) {
                // retrieve length even though we don't need it to workaround
                // bug in chrome cmd buffer param validation.
                GrGLsizei length = GR_GL_INIT_ZERO;
                GL_CALL(GetProgramInfoLog(fOutput.fProgramID,
                                          infoLen+1,
                                          &length,
                                          (char*)log.get()));
                GrPrintf((char*)log.get());
            }
            SkDEBUGFAIL("Error linking program");
            GL_CALL(DeleteProgram(fOutput.fProgramID));
            fOutput.fProgramID = 0;
            return false;
        }
    }

    if (!fUniformManager->isUsingBindUniform()) {
        fUniformManager->getUniformLocations(fOutput.fProgramID, fUniforms);
    }

    for (int i = 0; i < shadersToDelete.count(); ++i) {
      GL_CALL(DeleteShader(shadersToDelete[i]));
    }

    return true;
}
Пример #12
0
void GrResourceCache::addResource(const GrResourceKey& key,
                                  GrResource* resource,
                                  uint32_t ownershipFlags) {
    GrAssert(NULL == resource->getCacheEntry());
    // we don't expect to create new resources during a purge. In theory
    // this could cause purgeAsNeeded() into an infinite loop (e.g.
    // each resource destroyed creates and locks 2 resources and
    // unlocks 1 thereby causing a new purge).
    GrAssert(!fPurging);
    GrAutoResourceCacheValidate atcv(this);

    GrResourceEntry* entry = SkNEW_ARGS(GrResourceEntry, (key, resource));
    resource->setCacheEntry(entry);

    this->attachToHead(entry);
    fCache.insert(key, entry);

#if GR_DUMP_TEXTURE_UPLOAD
    GrPrintf("--- add resource to cache %p, count=%d bytes= %d %d\n",
             entry, fEntryCount, resource->sizeInBytes(), fEntryBytes);
#endif

    if (ownershipFlags & kHide_OwnershipFlag) {
        this->makeExclusive(entry);
    }

}
Пример #13
0
GrTexture* GrLockAndRefCachedBitmapTexture(GrContext* ctx,
                                           const SkBitmap& bitmap,
                                           const GrTextureParams* params) {
    GrTexture* result = NULL;

    bool cache = !bitmap.isVolatile();

    if (cache) {
        // If the bitmap isn't changing try to find a cached copy first.

        GrCacheID cacheID;
        generate_bitmap_cache_id(bitmap, &cacheID);

        GrTextureDesc desc;
        generate_bitmap_texture_desc(bitmap, &desc);

        result = ctx->findAndRefTexture(desc, cacheID, params);
    }
    if (NULL == result) {
        result = sk_gr_create_bitmap_texture(ctx, cache, params, bitmap);
    }
    if (NULL == result) {
        GrPrintf("---- failed to create texture for cache [%d %d]\n",
                    bitmap.width(), bitmap.height());
    }
    return result;
}
Пример #14
0
void GrDrawTarget::onDrawRect(const SkRect& rect,
                              const SkMatrix* matrix,
                              const SkRect* localRect,
                              const SkMatrix* localMatrix) {

    GrDrawState::AutoViewMatrixRestore avmr;
    if (NULL != matrix) {
        avmr.set(this->drawState(), *matrix);
    }

    set_vertex_attributes(this->drawState(), NULL != localRect);

    AutoReleaseGeometry geo(this, 4, 0);
    if (!geo.succeeded()) {
        GrPrintf("Failed to get space for vertices!\n");
        return;
    }

    size_t vsize = this->drawState()->getVertexSize();
    geo.positions()->setRectFan(rect.fLeft, rect.fTop, rect.fRight, rect.fBottom, vsize);
    if (NULL != localRect) {
        SkPoint* coords = GrTCast<SkPoint*>(GrTCast<intptr_t>(geo.vertices()) +
                                            sizeof(SkPoint));
        coords->setRectFan(localRect->fLeft, localRect->fTop,
                           localRect->fRight, localRect->fBottom,
                           vsize);
        if (NULL != localMatrix) {
            localMatrix->mapPointsWithStride(coords, vsize, 4);
        }
    }
    SkRect bounds;
    this->getDrawState().getViewMatrix().mapRect(&bounds, rect);

    this->drawNonIndexed(kTriangleFan_GrPrimitiveType, 0, 4, &bounds);
}
void GrBitmapTextContext::flushGlyphs() {
    if (NULL == fDrawTarget) {
        return;
    }

    GrDrawState* drawState = fDrawTarget->drawState();
    GrDrawState::AutoRestoreEffects are(drawState);
    drawState->setFromPaint(fPaint, SkMatrix::I(), fContext->getRenderTarget());

    if (fCurrVertex > 0) {
        // setup our sampler state for our text texture/atlas
        SkASSERT(SkIsAlign4(fCurrVertex));
        SkASSERT(fCurrTexture);
        GrTextureParams params(SkShader::kRepeat_TileMode, GrTextureParams::kNone_FilterMode);

        // This effect could be stored with one of the cache objects (atlas?)
        drawState->addCoverageEffect(
                                GrCustomCoordsTextureEffect::Create(fCurrTexture, params),
                                kGlyphCoordsAttributeIndex)->unref();

        if (NULL != fStrike && kARGB_GrMaskFormat == fStrike->getMaskFormat()) {
            drawState->setBlendFunc(fPaint.getSrcBlendCoeff(), fPaint.getDstBlendCoeff());
            drawState->setColor(0xffffffff);
        } else if (!GrPixelConfigIsAlphaOnly(fCurrTexture->config())) {
            if (kOne_GrBlendCoeff != fPaint.getSrcBlendCoeff() ||
                kISA_GrBlendCoeff != fPaint.getDstBlendCoeff() ||
                fPaint.numColorStages()) {
                GrPrintf("LCD Text will not draw correctly.\n");
            }
            // We don't use the GrPaint's color in this case because it's been premultiplied by
            // alpha. Instead we feed in a non-premultiplied color, and multiply its alpha by
            // the mask texture color. The end result is that we get
            //            mask*paintAlpha*paintColor + (1-mask*paintAlpha)*dstColor
            int a = SkColorGetA(fSkPaint.getColor());
            // paintAlpha
            drawState->setColor(SkColorSetARGB(a, a, a, a));
            // paintColor
            drawState->setBlendConstant(skcolor_to_grcolor_nopremultiply(fSkPaint.getColor()));
            drawState->setBlendFunc(kConstC_GrBlendCoeff, kISC_GrBlendCoeff);
        } else {
            // set back to normal in case we took LCD path previously.
            drawState->setBlendFunc(fPaint.getSrcBlendCoeff(), fPaint.getDstBlendCoeff());
            drawState->setColor(fPaint.getColor());
        }

        int nGlyphs = fCurrVertex / 4;
        fDrawTarget->setIndexSourceToBuffer(fContext->getQuadIndexBuffer());
        fDrawTarget->drawIndexedInstances(kTriangles_GrPrimitiveType,
                                          nGlyphs,
                                          4, 6, &fVertexBounds);

        fDrawTarget->resetVertexSource();
        fVertices = NULL;
        fMaxVertices = 0;
        fCurrVertex = 0;
        fVertexBounds.setLargestInverted();
        SkSafeSetNull(fCurrTexture);
    }
}
Пример #16
0
bool GrDrawTarget::setupDstReadIfNecessary(GrDeviceCoordTexture* dstCopy, const SkRect* drawBounds) {
    if (this->caps()->dstReadInShaderSupport() || !this->getDrawState().willEffectReadDstColor()) {
        return true;
    }
    GrRenderTarget* rt = this->drawState()->getRenderTarget();
    SkIRect copyRect;
    const GrClipData* clip = this->getClip();
    clip->getConservativeBounds(rt, &copyRect);

    if (NULL != drawBounds) {
        SkIRect drawIBounds;
        drawBounds->roundOut(&drawIBounds);
        if (!copyRect.intersect(drawIBounds)) {
#ifdef SK_DEBUG
            GrPrintf("Missed an early reject. Bailing on draw from setupDstReadIfNecessary.\n");
#endif
            return false;
        }
    } else {
#ifdef SK_DEBUG
        //GrPrintf("No dev bounds when dst copy is made.\n");
#endif
    }

    // MSAA consideration: When there is support for reading MSAA samples in the shader we could
    // have per-sample dst values by making the copy multisampled.
    GrTextureDesc desc;
    this->initCopySurfaceDstDesc(rt, &desc);
    desc.fWidth = copyRect.width();
    desc.fHeight = copyRect.height();

    GrAutoScratchTexture ast(fContext, desc, GrContext::kApprox_ScratchTexMatch);

    if (NULL == ast.texture()) {
        GrPrintf("Failed to create temporary copy of destination texture.\n");
        return false;
    }
    SkIPoint dstPoint = {0, 0};
    if (this->copySurface(ast.texture(), rt, copyRect, dstPoint)) {
        dstCopy->setTexture(ast.texture());
        dstCopy->setOffset(copyRect.fLeft, copyRect.fTop);
        return true;
    } else {
        return false;
    }
}
Пример #17
0
GrAtlasMgr::~GrAtlasMgr() {
    SkSafeUnref(fTexture);
    SkDELETE_ARRAY(fPlotArray);

    fGpu->unref();
#if FONT_CACHE_STATS
      GrPrintf("Num uploads: %d\n", g_UploadCount);
#endif
}
Пример #18
0
void GrGLExtensions::print(const char* sep) const {
    if (NULL == sep) {
        sep = " ";
    }
    int cnt = fStrings->count();
    for (int i = 0; i < cnt; ++i) {
        GrPrintf("%s%s", (*fStrings)[i].c_str(), (i < cnt - 1) ? sep : "");
    }
}
Пример #19
0
GrAtlas::~GrAtlas() {
    fAtlasMgr->freePlot(fPlot.fX, fPlot.fY);

    delete fRects;

#if GR_DEBUG
    --gCounter;
    GrPrintf("~GrAtlas %p [%d %d] %d\n", this, fPlot.fX, fPlot.fY, gCounter);
#endif
}
Пример #20
0
GrFontCache::~GrFontCache() {
    fCache.deleteAll();
    for (int i = 0; i < kAtlasCount; ++i) {
        delete fAtlasMgr[i];
    }
    fGpu->unref();
#if FONT_CACHE_STATS
      GrPrintf("Num purges: %d\n", g_PurgeCount);
#endif
}
Пример #21
0
/**
 * Destroying a resource may potentially trigger the unlock of additional
 * resources which in turn will trigger a nested purge. We block the nested
 * purge using the fPurging variable. However, the initial purge will keep
 * looping until either all resources in the cache are unlocked or we've met
 * the budget. There is an assertion in createAndLock to check against a
 * resource's destructor inserting new resources into the cache. If these
 * new resources were unlocked before purgeAsNeeded completed it could
 * potentially make purgeAsNeeded loop infinitely.
 */
void GrResourceCache::purgeAsNeeded() {
    if (!fPurging) {
        fPurging = true;
        bool withinBudget = false;
        bool changed = false;

        // The purging process is repeated several times since one pass
        // may free up other resources
        do {
            EntryList::Iter iter;

            changed = false;

            // Note: the following code relies on the fact that the
            // doubly linked list doesn't invalidate its data/pointers
            // outside of the specific area where a deletion occurs (e.g.,
            // in internalDetach)
            GrResourceEntry* entry = iter.init(fList, EntryList::Iter::kTail_IterStart);

            while (NULL != entry) {
                GrAutoResourceCacheValidate atcv(this);

                if (fEntryCount <= fMaxCount && fEntryBytes <= fMaxBytes) {
                    withinBudget = true;
                    break;
                }

                GrResourceEntry* prev = iter.prev();
                if (1 == entry->fResource->getRefCnt()) {
                    changed = true;

                    // remove from our cache
                    fCache.remove(entry->key(), entry);

                    // remove from our llist
                    this->internalDetach(entry);

        #if GR_DUMP_TEXTURE_UPLOAD
                    GrPrintf("--- ~resource from cache %p [%d %d]\n",
                             entry->resource(),
                             entry->resource()->width(),
                             entry->resource()->height());
        #endif

                    delete entry;
                }
                entry = prev;
            }
        } while (!withinBudget && changed);
        fPurging = false;
    }
}
Пример #22
0
GrAtlasMgr::~GrAtlasMgr() {
    for (size_t i = 0; i < GR_ARRAY_COUNT(fTexture); i++) {
        SkSafeUnref(fTexture[i]);
    }
    for (int i = 0; i < kCount_GrMaskFormats; ++i) {
        delete fPlotMgr[i];
    }

    fGpu->unref();
#if FONT_CACHE_STATS
      GrPrintf("Num uploads: %d\n", g_UploadCount);
#endif
}
Пример #23
0
GrFontCache::~GrFontCache() {
    SkTDynamicHash<GrTextStrike, GrFontDescKey>::Iter iter(&fCache);
    while (!iter.done()) {
        SkDELETE(&(*iter));
        ++iter;
    }
    for (int i = 0; i < kAtlasCount; ++i) {
        delete fAtlases[i];
    }
    fGpu->unref();
#if FONT_CACHE_STATS
      GrPrintf("Num purges: %d\n", g_PurgeCount);
#endif
}
Пример #24
0
bool GrGLShaderBuilder::finish(GrGLuint* outProgramId) {
    SK_TRACE_EVENT0("GrGLShaderBuilder::finish");

    GrGLuint programId = 0;
    GL_CALL_RET(programId, CreateProgram());
    if (!programId) {
        return false;
    }

    if (!this->compileAndAttachShaders(programId)) {
        GL_CALL(DeleteProgram(programId));
        return false;
    }

    this->bindProgramLocations(programId);

    GL_CALL(LinkProgram(programId));

    // Calling GetProgramiv is expensive in Chromium. Assume success in release builds.
    bool checkLinked = !fGpu->ctxInfo().isChromium();
#ifdef SK_DEBUG
    checkLinked = true;
#endif
    if (checkLinked) {
        GrGLint linked = GR_GL_INIT_ZERO;
        GL_CALL(GetProgramiv(programId, GR_GL_LINK_STATUS, &linked));
        if (!linked) {
            GrGLint infoLen = GR_GL_INIT_ZERO;
            GL_CALL(GetProgramiv(programId, GR_GL_INFO_LOG_LENGTH, &infoLen));
            SkAutoMalloc log(sizeof(char)*(infoLen+1));  // outside if for debugger
            if (infoLen > 0) {
                // retrieve length even though we don't need it to workaround
                // bug in chrome cmd buffer param validation.
                GrGLsizei length = GR_GL_INIT_ZERO;
                GL_CALL(GetProgramInfoLog(programId,
                                          infoLen+1,
                                          &length,
                                          (char*)log.get()));
                GrPrintf((char*)log.get());
            }
            SkDEBUGFAIL("Error linking program");
            GL_CALL(DeleteProgram(programId));
            return false;
        }
    }

    fUniformManager.getUniformLocations(programId, fUniforms);
    *outProgramId = programId;
    return true;
}
Пример #25
0
GrGpu* GrGpu::Create(GrEngine engine, GrPlatform3DContext context3D) {

    if (kOpenGL_Shaders_GrEngine == engine ||
        kOpenGL_Fixed_GrEngine == engine) {
        // If no GL bindings have been installed, fall-back to calling the
        // GL functions that have been linked with the executable.
        if (!GrGLGetGLInterface()) {
            GrGLSetDefaultGLInterface();
            // If there is no platform-default then just fail.
            if (!GrGLGetGLInterface()) {
                return NULL;
            }
        }
        if (!GrGLGetGLInterface()->validate(engine)) {
#if GR_DEBUG
            GrPrintf("Failed GL interface validation!");
#endif
            return NULL;
        }
    }

    GrGpu* gpu = NULL;

    switch (engine) {
        case kOpenGL_Shaders_GrEngine:
            {
#if 0 // old code path, will be removed soon
                gpu = new GrGpuGLShaders2;
#else
                gpu = new GrGpuGLShaders(context3D);
#endif
            }
            break;
        case kOpenGL_Fixed_GrEngine:
            gpu = new GrGpuGLFixed(context3D);
            break;
        case kDirect3D9_GrEngine:
            GrAssert(NULL != (void*)context3D);
#if GR_WIN32_BUILD
//            gpu = new GrGpuD3D9((IDirect3DDevice9*)context3D);
#endif
            break;
        default:
            GrAssert(!"unknown engine");
            break;
    }

    return gpu;
}
Пример #26
0
void GrGpu::printStats() const {
    if (GR_COLLECT_STATS) {
     GrPrintf(
     "-v-------------------------GPU STATS----------------------------v-\n"
     "Stats collection is: %s\n"
     "Draws: %04d, Verts: %04d, Indices: %04d\n"
     "ProgChanges: %04d, TexChanges: %04d, RTChanges: %04d\n"
     "TexCreates: %04d, RTCreates:%04d\n"
     "-^--------------------------------------------------------------^-\n",
     (GR_COLLECT_STATS ? "ON" : "OFF"),
    fStats.fDrawCnt, fStats.fVertexCnt, fStats.fIndexCnt,
    fStats.fProgChngCnt, fStats.fTextureChngCnt, fStats.fRenderTargetChngCnt,
    fStats.fTextureCreateCnt, fStats.fRenderTargetCreateCnt);
    }
}
Пример #27
0
GrAtlas::GrAtlas(GrAtlasMgr* mgr, int plotX, int plotY, GrMaskFormat format) {
    fAtlasMgr = mgr;    // just a pointer, not an owner
    fNext = NULL;
    fTexture = mgr->getTexture(format); // we're not an owner, just a pointer
    fPlot.set(plotX, plotY);

    fRects = GrRectanizer::Factory(GR_ATLAS_WIDTH - BORDER,
                                   GR_ATLAS_HEIGHT - BORDER);

    fMaskFormat = format;

#if GR_DEBUG
    GrPrintf(" GrAtlas %p [%d %d] %d\n", this, plotX, plotY, gCounter);
    gCounter += 1;
#endif
}
bool GrAndroidPathRenderer::onDrawPath(const SkPath& origPath,
                                       const SkStrokeRec& stroke,
                                       GrDrawTarget* target,
                                       bool antiAlias) {

    // generate verts using Android algorithm
    android::uirenderer::VertexBuffer vertices;
    android::uirenderer::PathRenderer::ConvexPathVertices(origPath, stroke, antiAlias, NULL,
                                                          &vertices);

    // set vertex layout depending on anti-alias
    GrVertexLayout layout = antiAlias ? GrDrawState::kCoverage_VertexLayoutBit : 0;

    // allocate our vert buffer
    int vertCount = vertices.getSize();
    GrDrawTarget::AutoReleaseGeometry geo(target, layout, vertCount, 0);
    if (!geo.succeeded()) {
        GrPrintf("Failed to get space for vertices!\n");
        return false;
    }

    // copy android verts to our vertex buffer
    if (antiAlias) {
        ColorVertex* outVert = reinterpret_cast<ColorVertex*>(geo.vertices());
        android::uirenderer::AlphaVertex* inVert =
            reinterpret_cast<android::uirenderer::AlphaVertex*>(vertices.getBuffer());

        for (int i = 0; i < vertCount; ++i) {
            // copy vertex position
            outVert->pos.set(inVert->position[0], inVert->position[1]);
            // copy alpha
            int coverage = static_cast<int>(inVert->alpha * 0xff);
            outVert->color = GrColorPackRGBA(coverage, coverage, coverage, coverage);
            ++outVert;
            ++inVert;
        }
    } else {
       size_t vsize = GrDrawState::VertexSize(layout);
       size_t copySize = vsize*vertCount;
       memcpy(geo.vertices(), vertices.getBuffer(), copySize);
    }

    // render it
    target->drawNonIndexed(kTriangleStrip_GrPrimitiveType, 0, vertCount);

    return true;
}
Пример #29
0
void GrDrawTarget::drawRect(const GrRect& rect,
                            const SkMatrix* matrix,
                            const GrRect* srcRects[],
                            const SkMatrix* srcMatrices[]) {
    GrVertexLayout layout = GetRectVertexLayout(srcRects);

    AutoReleaseGeometry geo(this, layout, 4, 0);
    if (!geo.succeeded()) {
        GrPrintf("Failed to get space for vertices!\n");
        return;
    }

    SetRectVertices(rect, matrix, srcRects,
                    srcMatrices, SK_ColorBLACK, layout, geo.vertices());

    drawNonIndexed(kTriangleFan_GrPrimitiveType, 0, 4);
}
Пример #30
0
void GrTextContext::flushGlyphs() {
    if (NULL == fDrawTarget) {
        return;
    }
    GrDrawState* drawState = fDrawTarget->drawState();
    if (fCurrVertex > 0) {
        // setup our sampler state for our text texture/atlas
        drawState->stage(kGlyphMaskStage)->reset();

        GrAssert(GrIsALIGN4(fCurrVertex));
        GrAssert(fCurrTexture);
        GrTextureParams params(SkShader::kRepeat_TileMode, false);
        drawState->createTextureEffect(kGlyphMaskStage, fCurrTexture, SkMatrix::I(), params);

        if (!GrPixelConfigIsAlphaOnly(fCurrTexture->config())) {
            if (kOne_GrBlendCoeff != fPaint.getSrcBlendCoeff() ||
                    kISA_GrBlendCoeff != fPaint.getDstBlendCoeff() ||
                    fPaint.hasColorStage()) {
                GrPrintf("LCD Text will not draw correctly.\n");
            }
            // setup blend so that we get mask * paintColor + (1-mask)*dstColor
            drawState->setBlendConstant(fPaint.getColor());
            drawState->setBlendFunc(kConstC_GrBlendCoeff, kISC_GrBlendCoeff);
            // don't modulate by the paint's color in the frag since we're
            // already doing it via the blend const.
            drawState->setColor(0xffffffff);
        } else {
            // set back to normal in case we took LCD path previously.
            drawState->setBlendFunc(fPaint.getSrcBlendCoeff(), fPaint.getDstBlendCoeff());
            drawState->setColor(fPaint.getColor());
        }

        int nGlyphs = fCurrVertex / 4;
        fDrawTarget->setIndexSourceToBuffer(fContext->getQuadIndexBuffer());
        fDrawTarget->drawIndexedInstances(kTriangles_GrPrimitiveType,
                                          nGlyphs,
                                          4, 6);
        fDrawTarget->resetVertexSource();
        fVertices = NULL;
        fMaxVertices = 0;
        fCurrVertex = 0;
        GrSafeSetNull(fCurrTexture);
    }
    drawState->disableStages();
    fDrawTarget = NULL;
}