You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

GLFW窗口缩放时Skia渲染画布对象闪烁抖动的修复咨询

Skia + GLFW 窗口 resize 时渲染对象闪烁抖动问题

问题描述

调整包含Skia渲染基础矩形的GLFW窗口尺寸时,矩形对象出现明显闪烁/抖动现象。

系统与编译信息

  • 硬件/系统:Apple M1 Pro,macOS Ventura 13.5.1
  • 编译命令:
/usr/bin/clang++ -w -g -I/Users/vasanth/skia -L/Users/vasanth/skia/out/RTTI -framework Metal -framework AppKit -framework OpenGL -framework IOKit -std=c++17 -lskia -lglfw3 sample.cpp -o out

源代码

#include <GLFW/glfw3.h>
#include <iostream>
#include "include/core/SkCanvas.h"
#include "include/core/SkPaint.h"
#include "include/core/SkRect.h"
#include "include/core/SkSurface.h"
#include "include/gpu/GrDirectContext.h"

SkCanvas* canvas;
SkImageInfo info;
int width, height;
GLFWwindow* window;
sk_sp<SkSurface> surface;

SkPaint getPaint(SkColor s) { SkPaint paint; paint.setColor(s); return paint; }

void SetSurfaceAndCanvas() {
    info = SkImageInfo::Make(width, height, SkColorType::kRGBA_8888_SkColorType, SkAlphaType::kPremul_SkAlphaType);
    surface = SkSurfaces::Raster(info);
    canvas = surface->getCanvas();
    canvas->translate(0.0f, height);
    canvas->scale(1.0f, -1.0f);
}
void Draw() {

    canvas->drawRect(SkRect::MakeXYWH(0, 0, width, height), getPaint(SK_ColorWHITE));
    canvas->drawRect(SkRect::MakeXYWH(0, 0, 250, 250), getPaint(SK_ColorRED));

    if (auto dContext = GrAsDirectContext(canvas->recordingContext())) { dContext->flushAndSubmit(); }
    std::vector<uint32_t> pixels(width * height * 4);
    surface->readPixels(info, pixels.data(), width * sizeof(uint32_t), 0, 0);
    glDrawPixels(width, height, GL_RGBA, GL_UNSIGNED_BYTE, pixels.data());
    glfwSwapBuffers(window);
}

void frame_buffer_size_callback(GLFWwindow* fwindow, int w, int h) {
    width = w; height = h;
    SetSurfaceAndCanvas();
    Draw();
}

int main() {
    glfwInit();
    window = glfwCreateWindow(500, 500, "Skia Test", nullptr, nullptr);
    glfwMakeContextCurrent(window);
    glfwGetFramebufferSize(window, &(width), &(height));
    glfwSetFramebufferSizeCallback(window, frame_buffer_size_callback);

    SetSurfaceAndCanvas();

    while (!glfwWindowShouldClose(window)) { 
        Draw();
        glfwPollEvents();
    }
    glfwDestroyWindow(window);
    glfwTerminate();
    return 0;
}

已尝试的解决方案

参考相关论坛建议,在窗口尺寸调整回调开始时设置窗口resizable属性为false,回调结束后恢复为true,但未解决闪烁问题。

内容的提问来源于stack exchange,提问作者vasanth_n

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.08 17:42:44