Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGermano Cavalcante <mano-wii>2021-04-29 20:48:59 +0300
committerGermano Cavalcante <germano.costa@ig.com.br>2021-04-30 16:42:13 +0300
commit04b6296e8165736d17fb5167e45a93178f9f71c2 (patch)
tree62229a42466cdf374f1a9b08da19de7a29e6286e /source/blender/python
parentc96506d54ad0aeb683896db50cf787d90840f702 (diff)
Python GPU: Add reference of PyObject GPU object to the GPU object itself
Instead of creating different python wrappers for the same GPU object, return the same `PyObject` created earlier. This also allows for more secure access to existing GPU objects. Reviewed By: brecht Differential Revision: https://developer.blender.org/D11044
Diffstat (limited to 'source/blender/python')
-rw-r--r--source/blender/python/gpu/gpu_py_framebuffer.c58
-rw-r--r--source/blender/python/gpu/gpu_py_framebuffer.h7
-rw-r--r--source/blender/python/gpu/gpu_py_texture.c32
-rw-r--r--source/blender/python/gpu/gpu_py_texture.h3
4 files changed, 76 insertions, 24 deletions
diff --git a/source/blender/python/gpu/gpu_py_framebuffer.c b/source/blender/python/gpu/gpu_py_framebuffer.c
index bc393aaafa4..0e58327737a 100644
--- a/source/blender/python/gpu/gpu_py_framebuffer.c
+++ b/source/blender/python/gpu/gpu_py_framebuffer.c
@@ -46,13 +46,7 @@
static int pygpu_framebuffer_valid_check(BPyGPUFrameBuffer *bpygpu_fb)
{
if (UNLIKELY(bpygpu_fb->fb == NULL)) {
- PyErr_SetString(PyExc_ReferenceError,
-#ifdef BPYGPU_USE_GPUOBJ_FREE_METHOD
- "GPU framebuffer was freed, no further access is valid"
-#else
- "GPU framebuffer: internal error"
-#endif
- );
+ PyErr_SetString(PyExc_ReferenceError, "GPU framebuffer was freed, no further access is valid");
return -1;
}
return 0;
@@ -68,10 +62,6 @@ static int pygpu_framebuffer_valid_check(BPyGPUFrameBuffer *bpygpu_fb)
static void pygpu_framebuffer_free_if_possible(GPUFrameBuffer *fb)
{
- if (!fb) {
- return;
- }
-
if (GPU_is_init()) {
GPU_framebuffer_free(fb);
}
@@ -80,6 +70,21 @@ static void pygpu_framebuffer_free_if_possible(GPUFrameBuffer *fb)
}
}
+static void pygpu_framebuffer_free_safe(BPyGPUFrameBuffer *self)
+{
+ if (self->fb) {
+#if GPU_USE_PY_REFERENCES
+ GPU_framebuffer_py_reference_set(self->fb, NULL);
+ if (!self->shared_reference)
+#endif
+ {
+ pygpu_framebuffer_free_if_possible(self->fb);
+ }
+
+ self->fb = NULL;
+ }
+}
+
/* Keep less than or equal to #FRAMEBUFFER_STACK_DEPTH */
#define GPU_PY_FRAMEBUFFER_STACK_LEN 16
@@ -336,7 +341,7 @@ static PyObject *pygpu_framebuffer__tp_new(PyTypeObject *UNUSED(self),
GPUFrameBuffer *fb_python = GPU_framebuffer_create("fb_python");
GPU_framebuffer_config_array(fb_python, config, color_attachements_len + 1);
- return BPyGPUFrameBuffer_CreatePyObject(fb_python);
+ return BPyGPUFrameBuffer_CreatePyObject(fb_python, false);
}
PyDoc_STRVAR(pygpu_framebuffer_is_bound_doc,
@@ -459,15 +464,14 @@ PyDoc_STRVAR(pygpu_framebuffer_free_doc,
static PyObject *pygpu_framebuffer_free(BPyGPUFrameBuffer *self)
{
PYGPU_FRAMEBUFFER_CHECK_OBJ(self);
- pygpu_framebuffer_free_if_possible(self->fb);
- self->fb = NULL;
+ pygpu_framebuffer_free_safe(self);
Py_RETURN_NONE;
}
#endif
static void BPyGPUFrameBuffer__tp_dealloc(BPyGPUFrameBuffer *self)
{
- pygpu_framebuffer_free_if_possible(self->fb);
+ pygpu_framebuffer_free_safe(self);
Py_TYPE(self)->tp_free((PyObject *)self);
}
@@ -531,13 +535,35 @@ PyTypeObject BPyGPUFrameBuffer_Type = {
/** \name Public API
* \{ */
-PyObject *BPyGPUFrameBuffer_CreatePyObject(GPUFrameBuffer *fb)
+PyObject *BPyGPUFrameBuffer_CreatePyObject(GPUFrameBuffer *fb, bool shared_reference)
{
BPyGPUFrameBuffer *self;
+#if GPU_USE_PY_REFERENCES
+ if (shared_reference) {
+ void **ref = GPU_framebuffer_py_reference_get(fb);
+ if (ref) {
+ /* Retrieve BPyGPUFrameBuffer reference. */
+ self = POINTER_OFFSET(ref, -offsetof(BPyGPUFrameBuffer, fb));
+ BLI_assert(self->fb == fb);
+ Py_INCREF(self);
+ return (PyObject *)self;
+ }
+ }
+#else
+ UNUSED_VARS(shared_reference);
+#endif
+
self = PyObject_New(BPyGPUFrameBuffer, &BPyGPUFrameBuffer_Type);
self->fb = fb;
+#if GPU_USE_PY_REFERENCES
+ self->shared_reference = shared_reference;
+
+ BLI_assert(GPU_framebuffer_py_reference_get(fb) == NULL);
+ GPU_framebuffer_py_reference_set(fb, &self->fb);
+#endif
+
return (PyObject *)self;
}
diff --git a/source/blender/python/gpu/gpu_py_framebuffer.h b/source/blender/python/gpu/gpu_py_framebuffer.h
index 7113e7c35aa..0049cc2fac7 100644
--- a/source/blender/python/gpu/gpu_py_framebuffer.h
+++ b/source/blender/python/gpu/gpu_py_framebuffer.h
@@ -28,6 +28,11 @@ extern PyTypeObject BPyGPUFrameBuffer_Type;
typedef struct BPyGPUFrameBuffer {
PyObject_HEAD struct GPUFrameBuffer *fb;
+
+#if GPU_USE_PY_REFERENCES
+ bool shared_reference;
+#endif
} BPyGPUFrameBuffer;
-PyObject *BPyGPUFrameBuffer_CreatePyObject(struct GPUFrameBuffer *fb) ATTR_NONNULL(1);
+PyObject *BPyGPUFrameBuffer_CreatePyObject(struct GPUFrameBuffer *fb, bool shared_reference)
+ ATTR_NONNULL(1);
diff --git a/source/blender/python/gpu/gpu_py_texture.c b/source/blender/python/gpu/gpu_py_texture.c
index 1ae65c1dd11..9cc6a9df8fa 100644
--- a/source/blender/python/gpu/gpu_py_texture.c
+++ b/source/blender/python/gpu/gpu_py_texture.c
@@ -247,7 +247,7 @@ static PyObject *pygpu_texture__tp_new(PyTypeObject *UNUSED(self), PyObject *arg
return NULL;
}
- return BPyGPUTexture_CreatePyObject(tex);
+ return BPyGPUTexture_CreatePyObject(tex, false);
}
PyDoc_STRVAR(pygpu_texture_width_doc, "Width of the texture.\n\n:type: `int`");
@@ -412,6 +412,9 @@ static PyObject *pygpu_texture_free(BPyGPUTexture *self)
static void BPyGPUTexture__tp_dealloc(BPyGPUTexture *self)
{
if (self->tex) {
+#if GPU_USE_PY_REFERENCES
+ GPU_texture_py_reference_set(self->tex, NULL);
+#endif
GPU_texture_free(self->tex);
}
Py_TYPE(self)->tp_free((PyObject *)self);
@@ -535,10 +538,7 @@ static PyObject *pygpu_texture_from_image(PyObject *UNUSED(self), PyObject *arg)
BKE_imageuser_default(&iuser);
GPUTexture *tex = BKE_image_get_gpu_texture(ima, &iuser, NULL);
- /* Increase the texture reference count. */
- GPU_texture_ref(tex);
-
- return BPyGPUTexture_CreatePyObject(tex);
+ return BPyGPUTexture_CreatePyObject(tex, true);
}
static struct PyMethodDef pygpu_texture__m_methods[] = {
@@ -595,13 +595,33 @@ PyObject *bpygpu_texture_init(void)
/** \name Public API
* \{ */
-PyObject *BPyGPUTexture_CreatePyObject(GPUTexture *tex)
+PyObject *BPyGPUTexture_CreatePyObject(GPUTexture *tex, bool shared_reference)
{
BPyGPUTexture *self;
+ if (shared_reference) {
+#if GPU_USE_PY_REFERENCES
+ void **ref = GPU_texture_py_reference_get(tex);
+ if (ref) {
+ /* Retrieve BPyGPUTexture reference. */
+ self = POINTER_OFFSET(ref, -offsetof(BPyGPUTexture, tex));
+ BLI_assert(self->tex == tex);
+ Py_INCREF(self);
+ return (PyObject *)self;
+ }
+#endif
+
+ GPU_texture_ref(tex);
+ }
+
self = PyObject_New(BPyGPUTexture, &BPyGPUTexture_Type);
self->tex = tex;
+#if GPU_USE_PY_REFERENCES
+ BLI_assert(GPU_texture_py_reference_get(tex) == NULL);
+ GPU_texture_py_reference_set(tex, &self->tex);
+#endif
+
return (PyObject *)self;
}
diff --git a/source/blender/python/gpu/gpu_py_texture.h b/source/blender/python/gpu/gpu_py_texture.h
index 5130273f971..457ddcfc931 100644
--- a/source/blender/python/gpu/gpu_py_texture.h
+++ b/source/blender/python/gpu/gpu_py_texture.h
@@ -33,4 +33,5 @@ typedef struct BPyGPUTexture {
int bpygpu_ParseTexture(PyObject *o, void *p);
PyObject *bpygpu_texture_init(void);
-PyObject *BPyGPUTexture_CreatePyObject(struct GPUTexture *tex) ATTR_NONNULL(1);
+PyObject *BPyGPUTexture_CreatePyObject(struct GPUTexture *tex, bool weak_reference)
+ ATTR_NONNULL(1);