2022-06-14 Canvas2d绘制动画不clear的话是不清屏的 底层触发多缓冲时走的buffer保留模式么?
- webcanvas走的保留模式,不clear的话 上一帧的内容依然保留
- nativecanvas是如何做的呢有两种方案。
增量绘制有两种方案
- 系统 EGL_SWAP_BEHAVIOR_PRESERVED_BIT
- 自己搞FBO,先绘制到FBO再swapbuffer前,绘制到在屏,swapbuffer结束后,切回到FBO
void AGHwSkSurfaceWrapAndroid::willCanvasSwap() {
unbindPBufferFbo();
drawBackBufferToFront();
}
void AGHwSkSurfaceWrapAndroid::didCanvasSwap() {
bindPBufferFbo();
}
skia创建surface的流程
GPU模式
MakeRenderTarget 离屏FBO
MakeFromBackendTexture 内建FBO并绑定给定的textureid
MakeFromBackendRenderTarget 使用已有FBO 默认是0
MakeFromAHardwareBuffer
GrBackendTexture
GrBackendRenderTarget
SK_API_HIDDEN static sk_sp<SkSurface> MakeFromBackendTexture(GrRecordingContext* context,
const GrBackendTexture& backendTexture,
GrSurfaceOrigin origin, int sampleCnt,
SkColorType colorType,
sk_sp<SkColorSpace> colorSpace,
const SkSurfaceProps* surfaceProps,
TextureReleaseProc textureReleaseProc = nullptr,
ReleaseContext releaseContext = nullptr);
static sk_sp<SkSurface> MakeFromBackendRenderTarget(GrRecordingContext* context,
const GrBackendRenderTarget& backendRenderTarget,
GrSurfaceOrigin origin,
SkColorType colorType,
sk_sp<SkColorSpace> colorSpace,
const SkSurfaceProps* surfaceProps,
RenderTargetReleaseProc releaseProc = nullptr,
ReleaseContext releaseContext = nullptr);
static sk_sp<SkSurface> MakeRenderTarget(GrRecordingContext* context, SkBudgeted budgeted,
const SkImageInfo& imageInfo,
int sampleCount, GrSurfaceOrigin surfaceOrigin,
const SkSurfaceProps* surfaceProps,
bool shouldCreateWithMips = false);
MakeFromBackendTexture 内建FBO并绑定给定的 textureid
SkSurface::MakeFromBackendTexture -> GrSurfaceDrawContext::MakeFromBackendTexture -> GrProxyProvider::wrapRenderableBackendTexture -> GrResourceProvider::wrapRenderableBackendTexture-> GrGLGpu::onWrapRenderableBackendTexture -> GrGLGpu::createRenderTargetObjects -> GL_CALL(GenFramebuffers(1, &rtIDs->fRTFBOID));
MakeFromBackendRenderTarget 使用已有FBO
onWrapBackendRenderTarget GrBackendObjectOwnership::kBorrowed 不删除外部传入的FBO
MakeRenderTarget 离屏FBO。内建FBO并且不指定textureid
context->priv().caps()->getDefaultBackendFormat(colorType, GrRenderable::kYes);
MakeFromAHardwareBuffer
AHardwareBuffer* buffer = nullptr;
sk_sp<SkSurface> surface = SkSurface::MakeFromAHardwareBuffer(context, buffer, surfaceOrigin,
nullptr, nullptr);
hardwareBuffer eglGetNativeClientBufferANDROID eglCreateImageKHR glEGLImageTargetTexture2DOES 到纹理id。
MakeFromAHardwareBuffer -》 GrAHardwareBufferUtils::MakeBackendTexture -》 MakeFromBackendTexture
static GrBackendTexture make_gl_backend_texture(GrDirectContext* dContext, AHardwareBuffer* hardwareBuffer)
while (GL_NO_ERROR != glGetError()) {} //clear GL errors
离屏和FBO有什么区别呢?
可以用于fallbackPbSurface场景 : 离屏Pbuffer有自己完整的context,可以创建1*1的 fallbackPbSurface 用于做fallbackPbSurface 逻辑。在销毁后异步调用makeCurrent场景。
FBO不需要切换glContext
bool forceFallbackPbSurface = is_onscreen && canvas_config.forceFallbackPbSurface && isSurfaceTextureDestroyed();
bool AEGLWindowContext::makeCurrent(bool forceFallbackPbSurface) {}
if (isSurfaceless) {
fallbackPbSurface = EGL_NO_SURFACE;
} else {
// 创建fallback surface逻辑
if (fallbackPbSurface == EGL_NO_SURFACE) {
EGLint pbufAttribs[] = {EGL_WIDTH, 1, EGL_HEIGHT, 1, EGL_NONE};
fallbackPbSurface = eglCreatePbufferSurface(eglDisplay, eglConfig, pbufAttribs);
}
}
网友评论