此篇讲图像采样 一、采样流程 在上一节里的流程图有写到,图像绘制的实际渲染发生在某个blitter的blitRect函数中,我们先看一个具体的blitRect实现。 void SkARGB32_Shader_Blitter::blitRect(int x, int y, int width, int height) { SkASSERT(x = 0 y = 0 x
此篇讲图像采样
一、采样流程
在上一节里的流程图有写到,图像绘制的实际渲染发生在某个blitter的blitRect函数中,我们先看一个具体的blitRect实现。
void SkARGB32_Shader_Blitter::blitRect(int x, int y, int width, int height) { SkASSERT(x >= 0 && y >= 0 && x + width <= fDevice.width() && y + height shadeSpan(x, y, device, width); span = device; while (--height > 0) { device = (uint32_t*)((char*)device + deviceRB); memcpy(device, span, width <shadeSpan(x, y, span, width); SkXfermode* xfer = fXfermode; if (xfer) { do { xfer->xfer32(device, span, width, NULL); y += 1; device = (uint32_t*)((char*)device + deviceRB); } while (--height > 0); } else { SkBlitRow::Proc32 proc = fProc32; do { proc(device, span, width, 255); y += 1; device = (uint32_t*)((char*)device + deviceRB); } while (--height > 0); } } return; } if (fShadeDirectlyIntoDevice) { void* ctx; SkShader::Context::ShadeProc shadeProc = shaderContext->asAShadeProc(&ctx); if (shadeProc) { do { shadeProc(ctx, x, y, device, width); y += 1; device = (uint32_t*)((char*)device + deviceRB); } while (--height > 0); } else { do { shaderContext->shadeSpan(x, y, device, width); y += 1; device = (uint32_t*)((char*)device + deviceRB); } while (--height > 0); } } else { SkXfermode* xfer = fXfermode; if (xfer) { do { shaderContext->shadeSpan(x, y, span, width); xfer->xfer32(device, span, width, NULL); y += 1; device = (uint32_t*)((char*)device + deviceRB); } while (--height > 0); } else { SkBlitRow::Proc32 proc = fProc32; do { shaderContext->shadeSpan(x, y, span, width); proc(device, span, width, 255); y += 1; device = (uint32_t*)((char*)device + deviceRB); } while (--height > 0); } }}
其中shadeSpan用来将shader中x,y坐标处的值取n个到dst的buffer中。
对于图像绘制时,它是 SkBitmapProcShader,这里是其实现:
void SkBitmapProcShader::BitmapProcShaderContext::shadeSpan(int x, int y, SkPMColor dstC[], int count) { co<em>本文来源gao.dai.ma.com搞@代*码(网$</em>nst SkBitmapProcState& state = *fState; if (state.getShaderProc32()) { state.getShaderProc32()(state, x, y, dstC, count); return; } uint32_t buffer[BUF_MAX + TEST_BUFFER_EXTRA]; SkBitmapProcState::MatrixProc mproc = state.getMatrixProc(); SkBitmapProcState::SampleProc32 sproc = state.getSampleProc32(); int max = state.maxCountForBufferSize(sizeof(buffer[0]) * BUF_MAX); SkASSERT(state.fBitmap->getPixels()); SkASSERT(state.fBitmap->pixelRef() == NULL || state.fBitmap->pixelRef()->isLocked()); for (;;) { int n = count; if (n > max) { n = max; } SkASSERT(n > 0 && n < BUF_MAX*2);#ifdef TEST_BUFFER_OVERRITE for (int i = 0; i < TEST_BUFFER_EXTRA; i++) { buffer[BUF_MAX + i] = TEST_PATTERN; }#endif mproc(state, buffer, n, x, y);#ifdef TEST_BUFFER_OVERRITE for (int j = 0; j 0); x += n; dstC += n; }}
流程如下:
1、存在 shaderProc,直接用
2、计算一次能处理的像素数count
3、mproc计算count个坐标,sproc根据坐标值去取色
注意到之前三个函数指针:
state.getShaderProc32
mproc = state.getMatrixProc
sproc = state.getShaderProc32
这三个函数指针在一开始创建blitter时设定: