Fix T59773: Raise exception if the gpu module is used in backgound mode.

Instead of crashing, an error message is displayed if a function of the gpu module is called without a GPU context.

Reviewers: brecht, campbellbarton, JacquesLucke, mont29

Subscribers: abdelmatinboulbayam, amir.shehata

Differential Revision: https://developer.blender.org/D4143
This commit is contained in:
mano-wii 2019-01-02 10:01:46 -02:00
parent c862c14339
commit 945007b32e
12 changed files with 113 additions and 128 deletions

View File

@ -38,6 +38,7 @@ extern "C" {
void GPU_init(void);
void GPU_exit(void);
bool GPU_is_initialized(void);
#ifdef __cplusplus
}

View File

@ -73,7 +73,6 @@ void GPU_init(void)
}
void GPU_exit(void)
{
if (!G.background) {
@ -92,3 +91,9 @@ void GPU_exit(void)
initialized = false;
}
bool GPU_is_initialized(void)
{
return initialized;
}

View File

@ -34,24 +34,22 @@ set(INC_SYS
)
set(SRC
gpu_py_api.c
gpu_py.c
gpu_py_batch.c
gpu_py_element.c
gpu_py_matrix.c
gpu_py_offscreen.c
gpu_py_primitive.c
gpu_py_select.c
gpu_py_shader.c
gpu_py_types.c
gpu_py_vertex_buffer.c
gpu_py_vertex_format.c
gpu_py_api.h
gpu_py.h
gpu_py_batch.h
gpu_py_element.h
gpu_py_matrix.h
gpu_py_offscreen.h
gpu_py_primitive.h
gpu_py_select.h
gpu_py_shader.h
gpu_py_types.h

View File

@ -34,11 +34,89 @@
#include "../generic/python_utildefines.h"
#include "GPU_init_exit.h"
#include "GPU_primitive.h"
#include "gpu_py_matrix.h"
#include "gpu_py_select.h"
#include "gpu_py_types.h"
#include "gpu_py_api.h" /* own include */
#include "gpu_py.h" /* own include */
/* -------------------------------------------------------------------- */
/** \name Utils to invalidate functions
* \{ */
bool bpygpu_is_initialized(void)
{
if (!GPU_is_initialized()) {
PyErr_SetString(
PyExc_SystemError,
"GPU functions for drawing are not available in background mode");
return false;
}
return true;
}
/** \} */
/* -------------------------------------------------------------------- */
/** \name Primitive Type Utils
* \{ */
int bpygpu_ParsePrimType(PyObject *o, void *p)
{
Py_ssize_t mode_id_len;
const char *mode_id = _PyUnicode_AsStringAndSize(o, &mode_id_len);
if (mode_id == NULL) {
PyErr_Format(PyExc_ValueError,
"expected a string, got %s",
Py_TYPE(o)->tp_name);
return 0;
}
#define MATCH_ID(id) \
if (mode_id_len == strlen(STRINGIFY(id))) { \
if (STREQ(mode_id, STRINGIFY(id))) { \
mode = GPU_PRIM_##id; \
goto success; \
} \
} ((void)0)
GPUPrimType mode;
MATCH_ID(POINTS);
MATCH_ID(LINES);
MATCH_ID(TRIS);
MATCH_ID(LINE_STRIP);
MATCH_ID(LINE_LOOP);
MATCH_ID(TRI_STRIP);
MATCH_ID(TRI_FAN);
MATCH_ID(LINE_STRIP_ADJ);
#undef MATCH_ID
PyErr_Format(PyExc_ValueError,
"unknown type literal: '%s'",
mode_id);
return 0;
success:
(*(GPUPrimType *)p) = mode;
return 1;
}
/** \} */
/* -------------------------------------------------------------------- */
/** \name GPU Module
* \{ */
PyDoc_STRVAR(GPU_doc,
"This module provides Python wrappers for the GPU implementation in Blender. "
@ -83,3 +161,5 @@ PyObject *BPyInit_gpu(void)
return mod;
}
/** \} */

View File

@ -22,9 +22,13 @@
* \ingroup bpygpu
*/
#ifndef __GPU_PY_API_H__
#define __GPU_PY_API_H__
#ifndef __GPU_PY_H__
#define __GPU_PY_H__
bool bpygpu_is_initialized(void);
int bpygpu_ParsePrimType(PyObject *o, void *p);
PyObject *BPyInit_gpu(void);
#endif /* __GPU_PY_API_H__ */
#endif /* __GPU_PY_H__ */

View File

@ -44,7 +44,7 @@
#include "../generic/py_capi_utils.h"
#include "gpu_py_primitive.h"
#include "gpu_py.h"
#include "gpu_py_shader.h"
#include "gpu_py_vertex_buffer.h"
#include "gpu_py_element.h"
@ -85,7 +85,8 @@ static PyObject *bpygpu_Batch_new(PyTypeObject *UNUSED(type), PyObject *args, Py
static const char *_keywords[] = {"type", "buf", "elem", NULL};
static _PyArg_Parser _parser = {"|$O&O!O!:GPUBatch.__new__", _keywords, 0};
if (!_PyArg_ParseTupleAndKeywordsFast(
if (!bpygpu_is_initialized() ||
!_PyArg_ParseTupleAndKeywordsFast(
args, kwds, &_parser,
bpygpu_ParsePrimType, &params.type_id,
&BPyGPUVertBuf_Type, &params.py_vertbuf,

View File

@ -36,7 +36,7 @@
#include "../generic/py_capi_utils.h"
#include "../generic/python_utildefines.h"
#include "gpu_py_primitive.h"
#include "gpu_py.h"
#include "gpu_py_element.h" /* own include */
@ -61,7 +61,8 @@ static PyObject *bpygpu_IndexBuf_new(PyTypeObject *UNUSED(type), PyObject *args,
static const char *_keywords[] = {"type", "seq", NULL};
static _PyArg_Parser _parser = {"$O&O:IndexBuf.__new__", _keywords, 0};
if (!_PyArg_ParseTupleAndKeywordsFast(
if (!bpygpu_is_initialized() ||
!_PyArg_ParseTupleAndKeywordsFast(
args, kwds, &_parser,
bpygpu_ParsePrimType, &params.type_id,
&params.seq))

View File

@ -53,6 +53,7 @@
#include "../generic/py_capi_utils.h"
#include "gpu_py.h"
#include "gpu_py_offscreen.h" /* own include */
@ -93,7 +94,8 @@ static PyObject *bpygpu_offscreen_new(PyTypeObject *UNUSED(self), PyObject *args
static const char *_keywords[] = {"width", "height", "samples", NULL};
static _PyArg_Parser _parser = {"ii|i:GPUOffScreen.__new__", _keywords, 0};
if (!_PyArg_ParseTupleAndKeywordsFast(
if (!bpygpu_is_initialized() ||
!_PyArg_ParseTupleAndKeywordsFast(
args, kwds, &_parser,
&width, &height, &samples))
{

View File

@ -1,81 +0,0 @@
/*
* ***** BEGIN GPL LICENSE BLOCK *****
*
* 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.
*
* Copyright 2015, Blender Foundation.
*
* ***** END GPL LICENSE BLOCK *****
*/
/** \file blender/python/gpu/gpu_py_primitive.c
* \ingroup bpygpu
*
* - Use ``bpygpu_`` for local API.
* - Use ``BPyGPU`` for public API.
*/
#include <Python.h>
#include "BLI_utildefines.h"
#include "GPU_primitive.h"
#include "gpu_py_primitive.h" /* own include */
/* -------------------------------------------------------------------- */
/** \name Primitive Utils
* \{ */
int bpygpu_ParsePrimType(PyObject *o, void *p)
{
Py_ssize_t mode_id_len;
const char *mode_id = _PyUnicode_AsStringAndSize(o, &mode_id_len);
if (mode_id == NULL) {
PyErr_Format(PyExc_ValueError,
"expected a string, got %s",
Py_TYPE(o)->tp_name);
return 0;
}
#define MATCH_ID(id) \
if (mode_id_len == strlen(STRINGIFY(id))) { \
if (STREQ(mode_id, STRINGIFY(id))) { \
mode = GPU_PRIM_##id; \
goto success; \
} \
} ((void)0)
GPUPrimType mode;
MATCH_ID(POINTS);
MATCH_ID(LINES);
MATCH_ID(TRIS);
MATCH_ID(LINE_STRIP);
MATCH_ID(LINE_LOOP);
MATCH_ID(TRI_STRIP);
MATCH_ID(TRI_FAN);
MATCH_ID(LINE_STRIP_ADJ);
#undef MATCH_ID
PyErr_Format(PyExc_ValueError,
"unknown type literal: '%s'",
mode_id);
return 0;
success:
(*(GPUPrimType *)p) = mode;
return 1;
}

View File

@ -1,30 +0,0 @@
/*
* ***** BEGIN GPL LICENSE BLOCK *****
*
* 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.
*
* ***** END GPL LICENSE BLOCK *****
*/
/** \file blender/python/gpu/gpu_py_primitive.h
* \ingroup bpygpu
*/
#ifndef __GPU_PY_PRIMITIVE_H__
#define __GPU_PY_PRIMITIVE_H__
int bpygpu_ParsePrimType(PyObject *o, void *p);
#endif /* __GPU_PY_PRIMITIVE_H__ */

View File

@ -36,6 +36,7 @@
#include "../generic/python_utildefines.h"
#include "../mathutils/mathutils.h"
#include "gpu_py.h"
#include "gpu_py_shader.h" /* own include */
#include "gpu_py_vertex_format.h"
@ -117,7 +118,8 @@ static PyObject *bpygpu_shader_new(PyTypeObject *UNUSED(type), PyObject *args, P
"libcode", "defines", NULL};
static _PyArg_Parser _parser = {"ss|$sss:GPUShader.__new__", _keywords, 0};
if (!_PyArg_ParseTupleAndKeywordsFast(
if (!bpygpu_is_initialized() ||
!_PyArg_ParseTupleAndKeywordsFast(
args, kwds, &_parser,
&params.vertexcode, &params.fragcode, &params.geocode,
&params.libcode, &params.defines))
@ -717,7 +719,9 @@ static PyObject *bpygpu_shader_from_builtin(PyObject *UNUSED(self), PyObject *ar
{
GPUBuiltinShader shader_id;
if (!bpygpu_ParseBultinShaderEnum(arg, &shader_id)) {
if (!bpygpu_is_initialized() ||
!bpygpu_ParseBultinShaderEnum(arg, &shader_id))
{
return NULL;
}

View File

@ -74,7 +74,7 @@
#include "../generic/blf_py_api.h"
#include "../generic/idprop_py_api.h"
#include "../generic/imbuf_py_api.h"
#include "../gpu/gpu_py_api.h"
#include "../gpu/gpu_py.h"
#include "../bmesh/bmesh_py_api.h"
#include "../mathutils/mathutils.h"