示例#1
0
文件: GrGpu.cpp 项目: Igalia/skia
bool GrGpu::attachStencilBufferToRenderTarget(GrRenderTarget* rt) {
    SkASSERT(NULL == rt->renderTargetPriv().getStencilBuffer());
    GrUniqueKey sbKey;

    int width = rt->width();
    int height = rt->height();
    if (this->caps()->oversizedStencilSupport()) {
        width  = SkNextPow2(width);
        height = SkNextPow2(height);
    }

    GrStencilBuffer::ComputeSharedStencilBufferKey(width, height, rt->numSamples(), &sbKey);
    SkAutoTUnref<GrStencilBuffer> sb(static_cast<GrStencilBuffer*>(
        this->getContext()->getResourceCache()->findAndRefUniqueResource(sbKey)));
    if (sb) {
        if (this->attachStencilBufferToRenderTarget(sb, rt)) {
            rt->renderTargetPriv().didAttachStencilBuffer(sb);
            return true;
        }
        return false;
    }
    if (this->createStencilBufferForRenderTarget(rt, width, height)) {
        GrStencilBuffer* sb = rt->renderTargetPriv().getStencilBuffer();
        sb->resourcePriv().setUniqueKey(sbKey);
        return true;
    } else {
        return false;
    }
}
SkGLDevice_FBO::SkGLDevice_FBO(const SkBitmap& bitmap, bool offscreen)
        : SkGLDevice(bitmap, offscreen) {
    fFBO = 0;
    fTextureID = 0;

    if (offscreen) {
        int nw = SkNextPow2(bitmap.rowBytesAsPixels());
        int nh = SkNextPow2(bitmap.height());
        
        glGenFramebuffersEXT(1, &fFBO);
        glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fFBO);

        glGenTextures(1, &fTextureID);
        glBindTexture(GL_TEXTURE_2D, fTextureID);
        SkGL::SetTexParamsClamp(false);
        glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, nw, nh, 0,
                     GL_RGBA, GL_UNSIGNED_BYTE, NULL);

        glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT,
                                  GL_TEXTURE_2D, fTextureID, 0);
        GLenum status = glCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT);
        if (status != GL_FRAMEBUFFER_COMPLETE_EXT) {
            SkDebugf("-- glCheckFramebufferStatusEXT %x\n", status);
        }

        // now reset back to "normal" drawing target
        glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
    }
}
示例#3
0
SkGLTextCache::Strike::Strike(Strike* next, int width, int height) {
    fStrikeWidth = SkNextPow2(SkMax32(kMinStrikeWidth, width));
    fStrikeHeight = SkNextPow2(height);
    fGlyphCount = 0;
    fNextFreeOffsetX = 0;
    fNext = next;

    fStrikeWidthShift = SkNextLog2(fStrikeWidth);
    fStrikeHeightShift = SkNextLog2(fStrikeHeight);
    
    if (next) {
        SkASSERT(next->fStrikeHeight == fStrikeHeight);
    }

    // create an empty texture to receive glyphs
    fTexName = 0;
    glGenTextures(1, &fTexName);
    glBindTexture(GL_TEXTURE_2D, fTexName);
    glTexImage2D(GL_TEXTURE_2D, 0, gTextTextureFormat, 
                 fStrikeWidth, fStrikeHeight, 0,
                 gTextTextureFormat, gTextTextureType, NULL);
    
    SK_glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
    SK_glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
    SK_glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
    SK_glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);    
}
示例#4
0
文件: SkGr.cpp 项目: tiftof/skia
void GrMakeKeyFromImageID(GrUniqueKey* key, uint32_t imageID,
                          U16CPU width, U16CPU height, SkIPoint origin,
                          const GrCaps& caps, SkImageUsageType usage) {
    const Stretch::Type stretches[] = {
        Stretch::kNone_Type,        // kUntiled_SkImageUsageType
        Stretch::kNearest_Type,     // kTiled_Unfiltered_SkImageUsageType
        Stretch::kBilerp_Type,      // kTiled_Filtered_SkImageUsageType
    };

    const bool isPow2 = SkIsPow2(width) && SkIsPow2(height);
    const bool needToStretch = !isPow2 &&
                               usage != kUntiled_SkImageUsageType &&
                               !caps.npotTextureTileSupport();

    if (needToStretch) {
        GrUniqueKey tmpKey;
        make_unstretched_key(&tmpKey, imageID, width, height, origin);

        Stretch stretch;
        stretch.fType = stretches[usage];
        stretch.fWidth = SkNextPow2(width);
        stretch.fHeight = SkNextPow2(height);
        if (!make_stretched_key(tmpKey, stretch, key)) {
            goto UNSTRETCHED;
        }
    } else {
        UNSTRETCHED:
        make_unstretched_key(key, imageID, width, height, origin);
    }
}
示例#5
0
/*  Return true if the bitmap cannot be supported in its current config as a
    texture, and it needs to be promoted to ARGB32.
 */
static bool needToPromoteTo32bit(const SkBitmap& bitmap) {
    if (bitmap.config() == SkBitmap::kIndex8_Config) {
#ifdef SK_GL_SUPPORT_COMPRESSEDTEXIMAGE2D
        const int w = bitmap.width();
        const int h = bitmap.height();
        if (SkNextPow2(w) == w && SkNextPow2(h) == h) {
            // we can handle Indx8 if we're a POW2
            return false;
        }
#endif
        return true;    // must promote to ARGB32
    }
    return false;
}
GrStencilAttachment* GrResourceProvider::attachStencilAttachment(GrRenderTarget* rt) {
    SkASSERT(rt);
    if (rt->renderTargetPriv().getStencilAttachment()) {
        return rt->renderTargetPriv().getStencilAttachment();
    }

    if (!rt->wasDestroyed() && rt->canAttemptStencilAttachment()) {
        GrUniqueKey sbKey;

        int width = rt->width();
        int height = rt->height();
#if 0
        if (this->caps()->oversizedStencilSupport()) {
            width  = SkNextPow2(width);
            height = SkNextPow2(height);
        }
#endif
        bool newStencil = false;
        GrStencilAttachment::ComputeSharedStencilAttachmentKey(width, height,
                                                               rt->numStencilSamples(), &sbKey);
        GrStencilAttachment* stencil = static_cast<GrStencilAttachment*>(
            this->findAndRefResourceByUniqueKey(sbKey));
        if (!stencil) {
            // Need to try and create a new stencil
            stencil = this->gpu()->createStencilAttachmentForRenderTarget(rt, width, height);
            if (stencil) {
                stencil->resourcePriv().setUniqueKey(sbKey);
                newStencil = true;
            }
        }
        if (rt->renderTargetPriv().attachStencilAttachment(stencil)) {
            if (newStencil) {
                // Right now we're clearing the stencil attachment here after it is
                // attached to a RT for the first time. When we start matching
                // stencil buffers with smaller color targets this will no longer
                // be correct because it won't be guaranteed to clear the entire
                // sb.
                // We used to clear down in the GL subclass using a special purpose
                // FBO. But iOS doesn't allow a stencil-only FBO. It reports unsupported
                // FBO status.
                this->gpu()->clearStencil(rt);
            }
        }
    }
    return rt->renderTargetPriv().getStencilAttachment();
}
示例#7
0
文件: GrGpu.cpp 项目: s4kibs4mi/skia
bool GrGpu::attachStencilAttachmentToRenderTarget(GrRenderTarget* rt) {
    SkASSERT(NULL == rt->renderTargetPriv().getStencilAttachment());
    GrUniqueKey sbKey;

    int width = rt->width();
    int height = rt->height();
#if 0
    if (this->caps()->oversizedStencilSupport()) {
        width  = SkNextPow2(width);
        height = SkNextPow2(height);
    }
#endif

    GrStencilAttachment::ComputeSharedStencilAttachmentKey(width, height,
        rt->numStencilSamples(), &sbKey);
    SkAutoTUnref<GrStencilAttachment> sb(static_cast<GrStencilAttachment*>(
        this->getContext()->getResourceCache()->findAndRefUniqueResource(sbKey)));
    if (sb) {
        if (this->attachStencilAttachmentToRenderTarget(sb, rt)) {
            rt->renderTargetPriv().didAttachStencilAttachment(sb);
            return true;
        }
        return false;
    }
    if (this->createStencilAttachmentForRenderTarget(rt, width, height)) {
        // Right now we're clearing the stencil buffer here after it is
        // attached to an RT for the first time. When we start matching
        // stencil buffers with smaller color targets this will no longer
        // be correct because it won't be guaranteed to clear the entire
        // sb.
        // We used to clear down in the GL subclass using a special purpose
        // FBO. But iOS doesn't allow a stencil-only FBO. It reports unsupported
        // FBO status.
        this->clearStencil(rt);
        GrStencilAttachment* sb = rt->renderTargetPriv().getStencilAttachment();
        sb->resourcePriv().setUniqueKey(sbKey);
        return true;
    } else {
        return false;
    }
}
示例#8
0
文件: SkGr.cpp 项目: picmonkey/skia
void GrMakeKeyFromImageID(GrUniqueKey* key, uint32_t imageID, const SkIRect& subset,
                          const GrCaps& caps, SkImageUsageType usage) {
    const SkGrStretch::Type stretches[] = {
        SkGrStretch::kNone_Type,        // kUntiled_SkImageUsageType
        SkGrStretch::kNearest_Type,     // kTiled_Unfiltered_SkImageUsageType
        SkGrStretch::kBilerp_Type,      // kTiled_Filtered_SkImageUsageType
    };

    if (!GrTextureUsageSupported(caps, subset.width(), subset.height(), usage)) {
        GrUniqueKey tmpKey;
        make_unstretched_key(&tmpKey, imageID, subset);

        SkGrStretch stretch;
        stretch.fType = stretches[usage];
        stretch.fWidth = SkNextPow2(subset.width());
        stretch.fHeight = SkNextPow2(subset.height());
        if (!GrMakeStretchedKey(tmpKey, stretch, key)) {
            goto UNSTRETCHED;
        }
    } else {
        UNSTRETCHED:
        make_unstretched_key(key, imageID, subset);
    }
}
示例#9
0
GLuint SkGL::BindNewTexture(const SkBitmap& origBitmap, SkPoint* max) {
    SkBitmap tmpBitmap;
    const SkBitmap* bitmap = &origBitmap;

    if (needToPromoteTo32bit(origBitmap)) {
        origBitmap.copyTo(&tmpBitmap, SkBitmap::kARGB_8888_Config);
        // now bitmap points to our temp, which has been promoted to 32bits
        bitmap = &tmpBitmap;
    }

    GLenum format, type;
    if (!canBeTexture(*bitmap, &format, &type)) {
        return 0;
    }

    SkAutoLockPixels alp(*bitmap);
    if (!bitmap->readyToDraw()) {
        return 0;
    }

    GLuint  textureName;
    glGenTextures(1, &textureName);

    glBindTexture(GL_TEXTURE_2D, textureName);

    // express rowbytes as a number of pixels for ow
    int ow = bitmap->rowBytesAsPixels();
    int oh = bitmap->height();
    int nw = SkNextPow2(ow);
    int nh = SkNextPow2(oh);

    glPixelStorei(GL_UNPACK_ALIGNMENT, bitmap->bytesPerPixel());

    // check if we need to scale to create power-of-2 dimensions
#ifdef SK_GL_SUPPORT_COMPRESSEDTEXIMAGE2D
    if (SkBitmap::kIndex8_Config == bitmap->config()) {
        size_t imagesize = bitmap->getSize() + SK_GL_SIZE_OF_PALETTE;
        SkAutoMalloc storage(imagesize);

        build_compressed_data(storage.get(), *bitmap);
        // we only support POW2 here (GLES 1.0 restriction)
        SkASSERT(ow == nw);
        SkASSERT(oh == nh);
        glCompressedTexImage2D(GL_TEXTURE_2D, 0, format, ow, oh, 0,
                               imagesize, storage.get());
    } else  // fall through to non-compressed logic
#endif
    {
        if (ow != nw || oh != nh) {
            glTexImage2D(GL_TEXTURE_2D, 0, format, nw, nh, 0,
                         format, type, NULL);
            glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, ow, oh,
                            format, type, bitmap->getPixels());
        } else {
            // easy case, the bitmap is already pow2
            glTexImage2D(GL_TEXTURE_2D, 0, format, ow, oh, 0,
                         format, type, bitmap->getPixels());
        }
    }

#ifdef TRACE_TEXTURE_CREATION
    SkDebugf("--- new texture [%d] size=(%d %d) bpp=%d\n", textureName, ow, oh,
             bitmap->bytesPerPixel());
#endif

    if (max) {
        max->fX = SkFixedToScalar(bitmap->width() << (16 - SkNextLog2(nw)));
        max->fY = SkFixedToScalar(oh << (16 - SkNextLog2(nh)));
    }
    return textureName;
}
示例#10
0
static inline bool check_rounding(int value, int dividend, int divisor) {
    // returns true if the value is greater than floor(dividend/divisor)
    // and less than SkNextPow2(ceil(dividend - divisor))
    return (((divisor * value) > (dividend - divisor))
            && value <= SkNextPow2(((dividend - 1) / divisor) + 1));
}
示例#11
0
SkGLTextCache::Strike*
SkGLTextCache::Strike::findGlyph(const SkGlyph& glyph, int* offset) {
    Strike* strike = this;
    SkDEBUGCODE(const int height = SkNextPow2(glyph.fHeight);)
    
    do {