Page MenuHome

Grease Pencil: drawing shapes on surface causes intense viewport flickering
Closed, ResolvedPublic

Description

System Information
Operating system: Linux-4.13.10-041310-generic-x86_64-with-debian-stretch-sid 64 Bits
Graphics card: GeForce GTX 1050/PCIe/SSE2 NVIDIA Corporation 4.5.0 NVIDIA 390.67

Blender Version
Broken: version: 2.80 (sub 74), branch: master, commit date: 2019-06-19 18:29, hash: rBd30f72dfd8ac

Drawing GP shapes on the surface of an object causes viewport flickering.

See video demo.

Exact steps for others to reproduce the error

  • open the blend file
    • everything is setup for surface drawing already
  • start drawing lines or other shapes
    • the viewport should flicker(cyclce through various buffers?)

Event Timeline

Can confirm. Doesn't work on 'd30f72dfd8ac'
Seems to have worked fine on Hash: '12da679fa094' though it could've also worked later on. Its just the latest one before today's build that I have on my computer.

Ok it is caused by a VERY bad usage of DRW in GPencil. My patch just unveiled the problem.

@Antonio Vazquez (antoniov) The issue comes from these lines. When drawing a line, the draw depth function is called first, and only used basic engine and GPencil. But then when the viewport is redrawn, an other set of engine is enabled which reset all engines data for this viewport.

This makes stl->storage->buffer_stroke false even if the stl->storage->buffer_stroke is still valid. That leads to memory leak and other
So the easy fix should be to free just after finishing drawing.

In the long run we should reuse the batches to avoid memory allocations.

Source of the issue.

if (stl->storage->buffer_stroke) {
  GPU_BATCH_DISCARD_SAFE(e_data->batch_buffer_stroke);
  MEM_SAFE_FREE(e_data->batch_buffer_stroke);
  stl->storage->buffer_stroke = false;
}
...
/* temp textures for ping-pong buffers */
e_data.temp_depth_tx_a = DRW_texture_pool_query_2d(
    size[0], size[1], GPU_DEPTH_COMPONENT24, &draw_engine_gpencil_type);
...

Don't use e_data for things that will change or can be volatile. Use stl->g_data for that and be sure to reset it before reuse

Pretty much all these vars should be inside stl->g_data

/* textures */
struct GPUTexture *background_depth_tx;
struct GPUTexture *background_color_tx;

struct GPUTexture *gpencil_blank_texture;

/* runtime pointers texture */
struct GPUTexture *input_depth_tx;
struct GPUTexture *input_color_tx;

/* working textures */
struct GPUTexture *temp_color_tx_a;
struct GPUTexture *temp_depth_tx_a;

struct GPUTexture *temp_color_tx_b;
struct GPUTexture *temp_depth_tx_b;

struct GPUTexture *temp_color_tx_fx;
struct GPUTexture *temp_depth_tx_fx;

/* for buffer only one batch is nedeed because the drawing is only of one stroke */
GPUBatch *batch_buffer_stroke;
GPUBatch *batch_buffer_fill;
GPUBatch *batch_buffer_ctrlpoint;

/* grid geometry */
GPUBatch *batch_grid;

If you are using temp textures, then you cannot assume they will be the same when the next redraw comes up. Use txl and real texture for that.

@Clément Foucault (fclem) I will take a look of the bug, but not sure now it's the moment to make the other changes so near of 2.80 release date. I thinkis better wait for 2.81.

I have tested and in Windows 10 NVIDIA RTX2080TI I'm unable to reproduce it.

EDIT: With a new file I can reproduce it now.