[Bf-blender-cvs] [9db3d1951da] master: Fix typo; Documentation; Expose layer for framebuffer attachament; Add framebuffer viewport setter; Remove framebuffer restore; Expose framebuffer push/pop stack API; Remove blend modes; Remove depth_range_set; Implement GPU_face_culling, GPU_front_facing, GPU_point_size, GPU_line_width, GPU_viewport, GPU_color_mask and GPU_depth_mask

Germano Cavalcantemano-wii noreply at git.blender.org
Mon Jan 11 00:30:34 CET 2021


Commit: 9db3d1951da15254efbbcf028176facb78118ec1
Author: Germano Cavalcantemano-wii
Date:   Fri Dec 11 01:18:24 2020 -0300
Branches: master
https://developer.blender.org/rB9db3d1951da15254efbbcf028176facb78118ec1

Fix typo; Documentation; Expose layer for framebuffer attachament; Add framebuffer viewport setter; Remove framebuffer restore; Expose framebuffer push/pop stack API; Remove blend modes; Remove depth_range_set; Implement GPU_face_culling, GPU_front_facing, GPU_point_size, GPU_line_width, GPU_viewport, GPU_color_mask and GPU_depth_mask

===================================================================

M	source/blender/gpu/GPU_framebuffer.h
M	source/blender/gpu/intern/gpu_framebuffer.cc
M	source/blender/python/generic/py_capi_utils.c
M	source/blender/python/generic/py_capi_utils.h
M	source/blender/python/gpu/CMakeLists.txt
M	source/blender/python/gpu/gpu_py_api.c
A	source/blender/python/gpu/gpu_py_framebuffer.c
A	source/blender/python/gpu/gpu_py_framebuffer.h
A	source/blender/python/gpu/gpu_py_state.c
A	source/blender/python/gpu/gpu_py_state.h
A	source/blender/python/gpu/gpu_py_texture.c
A	source/blender/python/gpu/gpu_py_texture.h
M	source/blender/python/gpu/gpu_py_types.c
M	source/blender/python/gpu/gpu_py_types.h

===================================================================

diff --git a/source/blender/gpu/GPU_framebuffer.h b/source/blender/gpu/GPU_framebuffer.h
index c0f91756bf6..726dcbf0174 100644
--- a/source/blender/gpu/GPU_framebuffer.h
+++ b/source/blender/gpu/GPU_framebuffer.h
@@ -209,6 +209,10 @@ void GPU_framebuffer_recursive_downsample(GPUFrameBuffer *fb,
                                           void (*callback)(void *userData, int level),
                                           void *userData);
 
+void GPU_framebuffer_push(GPUFrameBuffer *fb);
+GPUFrameBuffer *GPU_framebuffer_pop(void);
+uint GPU_framebuffer_stack_level_get(void);
+
 /* GPU OffScreen
  * - wrapper around frame-buffer and texture for simple off-screen drawing
  */
diff --git a/source/blender/gpu/intern/gpu_framebuffer.cc b/source/blender/gpu/intern/gpu_framebuffer.cc
index d5d7994a154..910bdc531fe 100644
--- a/source/blender/gpu/intern/gpu_framebuffer.cc
+++ b/source/blender/gpu/intern/gpu_framebuffer.cc
@@ -476,10 +476,8 @@ void GPU_framebuffer_recursive_downsample(GPUFrameBuffer *gpu_fb,
 /** \} */
 
 /* -------------------------------------------------------------------- */
-/** \name GPUOffScreen
+/** \name Framebuffer Push/Pop
  *
- * Container that holds a frame-buffer and its textures.
- * Might be bound to multiple contexts.
  * \{ */
 
 #define FRAMEBUFFER_STACK_DEPTH 16
@@ -489,22 +487,36 @@ static struct {
   uint top;
 } FrameBufferStack = {{nullptr}};
 
-static void gpuPushFrameBuffer(GPUFrameBuffer *fb)
+void GPU_framebuffer_push(GPUFrameBuffer *fb)
 {
   BLI_assert(FrameBufferStack.top < FRAMEBUFFER_STACK_DEPTH);
   FrameBufferStack.framebuffers[FrameBufferStack.top] = fb;
   FrameBufferStack.top++;
 }
 
-static GPUFrameBuffer *gpuPopFrameBuffer()
+GPUFrameBuffer *GPU_framebuffer_pop(void)
 {
   BLI_assert(FrameBufferStack.top > 0);
   FrameBufferStack.top--;
   return FrameBufferStack.framebuffers[FrameBufferStack.top];
 }
 
+uint GPU_framebuffer_stack_level_get(void)
+{
+  return FrameBufferStack.top;
+}
+
 #undef FRAMEBUFFER_STACK_DEPTH
 
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name GPUOffScreen
+ *
+ * Container that holds a frame-buffer and its textures.
+ * Might be bound to multiple contexts.
+ * \{ */
+
 #define MAX_CTX_FB_LEN 3
 
 struct GPUOffScreen {
@@ -614,7 +626,7 @@ void GPU_offscreen_bind(GPUOffScreen *ofs, bool save)
 {
   if (save) {
     GPUFrameBuffer *fb = GPU_framebuffer_active_get();
-    gpuPushFrameBuffer(fb);
+    GPU_framebuffer_push(fb);
   }
   unwrap(gpu_offscreen_fb_get(ofs))->bind(false);
 }
@@ -623,7 +635,7 @@ void GPU_offscreen_unbind(GPUOffScreen *UNUSED(ofs), bool restore)
 {
   GPUFrameBuffer *fb = nullptr;
   if (restore) {
-    fb = gpuPopFrameBuffer();
+    fb = GPU_framebuffer_pop();
   }
 
   if (fb) {
diff --git a/source/blender/python/generic/py_capi_utils.c b/source/blender/python/generic/py_capi_utils.c
index d944cb435d0..24793a08ba9 100644
--- a/source/blender/python/generic/py_capi_utils.c
+++ b/source/blender/python/generic/py_capi_utils.c
@@ -282,6 +282,16 @@ int PyC_ParseStringEnum(PyObject *o, void *p)
   return 0;
 }
 
+const char *PyC_StringEnum_find_id(struct PyC_StringEnum *e, const int value)
+{
+  for (int i = 0; e->items[i].id; i++) {
+    if (e->items[i].value == value) {
+      return e->items[i].id;
+    }
+  }
+  return NULL;
+}
+
 /* silly function, we dont use arg. just check its compatible with __deepcopy__ */
 int PyC_CheckArgs_DeepCopy(PyObject *args)
 {
diff --git a/source/blender/python/generic/py_capi_utils.h b/source/blender/python/generic/py_capi_utils.h
index f0875b82c3c..6f41f9229c8 100644
--- a/source/blender/python/generic/py_capi_utils.h
+++ b/source/blender/python/generic/py_capi_utils.h
@@ -142,6 +142,7 @@ struct PyC_StringEnum {
 };
 
 int PyC_ParseStringEnum(PyObject *o, void *p);
+const char *PyC_StringEnum_find_id(struct PyC_StringEnum *e, const int value);
 
 int PyC_CheckArgs_DeepCopy(PyObject *args);
 
diff --git a/source/blender/python/gpu/CMakeLists.txt b/source/blender/python/gpu/CMakeLists.txt
index 7f6fd9eefab..25670a9be69 100644
--- a/source/blender/python/gpu/CMakeLists.txt
+++ b/source/blender/python/gpu/CMakeLists.txt
@@ -36,10 +36,13 @@ set(SRC
   gpu_py_api.c
   gpu_py_batch.c
   gpu_py_element.c
+  gpu_py_framebuffer.c
   gpu_py_matrix.c
   gpu_py_offscreen.c
   gpu_py_select.c
   gpu_py_shader.c
+  gpu_py_state.c
+  gpu_py_texture.c
   gpu_py_types.c
   gpu_py_vertex_buffer.c
   gpu_py_vertex_format.c
@@ -47,10 +50,13 @@ set(SRC
   gpu_py_api.h
   gpu_py_batch.h
   gpu_py_element.h
+  gpu_py_framebuffer.h
   gpu_py_matrix.h
   gpu_py_offscreen.h
   gpu_py_select.h
   gpu_py_shader.h
+  gpu_py_state.h
+  gpu_py_texture.h
   gpu_py_types.h
   gpu_py_vertex_buffer.h
   gpu_py_vertex_format.h
diff --git a/source/blender/python/gpu/gpu_py_api.c b/source/blender/python/gpu/gpu_py_api.c
index 33130291162..70bf04c0992 100644
--- a/source/blender/python/gpu/gpu_py_api.c
+++ b/source/blender/python/gpu/gpu_py_api.c
@@ -35,6 +35,7 @@
 
 #include "gpu_py_matrix.h"
 #include "gpu_py_select.h"
+#include "gpu_py_state.h"
 #include "gpu_py_types.h"
 
 #include "gpu_py_api.h" /* own include */
@@ -134,6 +135,12 @@ PyObject *BPyInit_gpu(void)
   PyModule_AddObject(mod, "shader", (submodule = BPyInit_gpu_shader()));
   PyDict_SetItem(sys_modules, PyModule_GetNameObject(submodule), submodule);
 
+  PyModule_AddObject(mod, "framebuffer", (submodule = BPyInit_gpu_framebuffer()));
+  PyDict_SetItem(sys_modules, PyModule_GetNameObject(submodule), submodule);
+
+  PyModule_AddObject(mod, "state", (submodule = BPyInit_gpu_state()));
+  PyDict_SetItem(sys_modules, PyModule_GetNameObject(submodule), submodule);
+
   return mod;
 }
 
diff --git a/source/blender/python/gpu/gpu_py_framebuffer.c b/source/blender/python/gpu/gpu_py_framebuffer.c
new file mode 100644
index 00000000000..248e592530f
--- /dev/null
+++ b/source/blender/python/gpu/gpu_py_framebuffer.c
@@ -0,0 +1,480 @@
+/*
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ */
+
+/** \file
+ * \ingroup bpygpu
+ *
+ * This file defines the framebuffer functionalities of the 'gpu' module
+ * used for off-screen OpenGL rendering.
+ *
+ * - Use ``bpygpu_`` for local API.
+ * - Use ``BPyGPU`` for public API.
+ */
+
+#include <Python.h>
+
+#include "GPU_context.h"
+#include "GPU_framebuffer.h"
+#include "GPU_init_exit.h"
+
+#include "../generic/py_capi_utils.h"
+#include "../generic/python_utildefines.h"
+#include "../mathutils/mathutils.h"
+
+#include "gpu_py_api.h"
+#include "gpu_py_texture.h"
+
+#include "gpu_py_framebuffer.h" /* own include */
+
+/* -------------------------------------------------------------------- */
+/** \name GPUFrameBuffer Common Utilities
+ * \{ */
+
+static int py_framebuffer_valid_check(BPyGPUFrameBuffer *bpygpu_fb)
+{
+  if (UNLIKELY(bpygpu_fb->fb == NULL)) {
+    PyErr_SetString(PyExc_ReferenceError, "GPU framebuffer was freed, no further access is valid");
+    return -1;
+  }
+  return 0;
+}
+
+#define PY_FRAMEBUFFER_CHECK_OBJ(bpygpu) \
+  { \
+    if (UNLIKELY(py_framebuffer_valid_check(bpygpu) == -1)) { \
+      return NULL; \
+    } \
+  } \
+  ((void)0)
+
+static void py_framebuffer_free_if_possible(GPUFrameBuffer *fb)
+{
+  if (!fb) {
+    return;
+  }
+
+  if (GPU_is_init()) {
+    GPU_framebuffer_free(fb);
+  }
+  else {
+    printf("PyFramebuffer freed after the context has been destroyed.\n");
+  }
+}
+
+/* Keep less than or equal to #FRAMEBUFFER_STACK_DEPTH */
+#define GPU_PY_FRAMEBUFFER_STACK_LEN 16
+
+static bool py_framebuffer_stack_push_or_error(GPUFrameBuffer *fb)
+{
+  if (GPU_framebuffer_stack_level_get() >= GPU_PY_FRAMEBUFFER_STACK_LEN) {
+    PyErr_SetString(
+        PyExc_RuntimeError,
+        "Maximum framebuffer stack depth " STRINGIFY(GPU_PY_FRAMEBUFFER_STACK_LEN) " reached");
+    return false;
+  }
+  GPU_framebuffer_push(fb);
+  GPU_framebuffer_bind(fb);
+  return true;
+}
+
+static bool py_framebuffer_stack_pop_or_error(void)
+{
+  if (GPU_framebuffer_stack_level_get() == 0) {
+    PyErr_SetString(PyExc_RuntimeError, "Minimum framebuffer stack depth reached");
+    return false;
+  }
+
+  GPUFrameBuffer *fb = GPU_framebuffer_pop();
+  GPU_framebuffer_bind(fb);
+  return true;
+}
+
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name GPUFramebuffer Type
+ * \{ */
+
+static PyObject *py_framebuffer_new(PyTypeObject *UNUSED(self), PyObject *args, PyObject *kwds)
+{
+  BPYGPU_IS_INIT_OR_ERROR_OBJ;
+  if (PyTuple_GET_SIZE(args) || (kwds && PyDict_Size(kwds))) {
+    PyErr_SetString(PyExc_ValueError, "This function takes no arguments");
+    return NULL;
+  }
+
+  if (!GPU_context_active_get()) {
+    PyErr_SetString(PyExc_RuntimeError, "No active GPU context found");
+    return NULL;
+  }
+
+  GPUFrameBuffer *fb = GPU_framebuffer_create("python_fb");
+  return BPyGPUFrameBuffer_CreatePyObject(fb);
+}
+
+static PyObject *py_framebuffer_viewport_get(BPyGPUFrameBuffer *self, void *UNUSED(type))
+{
+  PY_FRAMEBUFFER_CHECK_OBJ(self);
+  int viewport[4];
+  GPU_framebuffer_viewport_get(self->fb, viewport);
+
+  PyObject *ret = PyTuple_New(4);
+  PyTuple_SET_ITEMS(ret,
+                    PyLong_FromLong(viewport[0]),
+                    PyLong_FromLong(viewport[1]),
+                    PyLong_FromLong(viewport[2]),
+                    PyLong_FromLong(viewport[3]));
+  return ret;
+}
+
+static int py_framebuffer_viewport_set(BPyGPUFrameBuffer *self,
+                                       PyObject *py_values,
+                                       void *UNUSED(type))
+{
+  in

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list