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:
authorCampbell Barton <ideasman42@gmail.com>2019-06-29 10:48:51 +0300
committerCampbell Barton <ideasman42@gmail.com>2019-06-29 11:21:53 +0300
commitf021635bd5311bff28d44989f2fc14d3e37215a8 (patch)
tree70bbaabd9208743d6a79bf14a1adef0b42dcbc6d
parent71086995a552d41be361e49e7c3f3cfbfffa4dac (diff)
WM: support window context override
This makes it possible to take a screenshot from any window in Python.
-rw-r--r--source/blender/editors/screen/screendump.c50
-rw-r--r--source/blender/windowmanager/WM_api.h2
-rw-r--r--source/blender/windowmanager/intern/wm_window.c44
3 files changed, 53 insertions, 43 deletions
diff --git a/source/blender/editors/screen/screendump.c b/source/blender/editors/screen/screendump.c
index 3b763c7d47a..e5552314a6e 100644
--- a/source/blender/editors/screen/screendump.c
+++ b/source/blender/editors/screen/screendump.c
@@ -43,8 +43,6 @@
#include "BKE_main.h"
#include "BKE_report.h"
-#include "BIF_gl.h"
-
#include "RNA_access.h"
#include "RNA_define.h"
@@ -63,59 +61,25 @@ typedef struct ScreenshotData {
ImageFormatData im_format;
} ScreenshotData;
-static void screenshot_read_pixels(int x, int y, int w, int h, unsigned char *rect)
-{
- int i;
-
- glReadPixels(x, y, w, h, GL_RGBA, GL_UNSIGNED_BYTE, rect);
- glFinish();
-
- /* clear alpha, it is not set to a meaningful value in opengl */
- for (i = 0, rect += 3; i < w * h; i++, rect += 4) {
- *rect = 255;
- }
-}
-
-/* get shot from frontbuffer */
-static unsigned int *screenshot(bContext *C, int *dumpsx, int *dumpsy)
-{
- wmWindow *win = CTX_wm_window(C);
- int x = 0, y = 0;
- unsigned int *dumprect = NULL;
-
- x = 0;
- y = 0;
- *dumpsx = WM_window_pixels_x(win);
- *dumpsy = WM_window_pixels_y(win);
-
- if (*dumpsx && *dumpsy) {
-
- dumprect = MEM_mallocN(sizeof(int) * (*dumpsx) * (*dumpsy), "dumprect");
- glReadBuffer(GL_FRONT);
- screenshot_read_pixels(x, y, *dumpsx, *dumpsy, (unsigned char *)dumprect);
- glReadBuffer(GL_BACK);
- }
-
- return dumprect;
-}
-
/* call from both exec and invoke */
static int screenshot_data_create(bContext *C, wmOperator *op)
{
- unsigned int *dumprect;
- int dumpsx, dumpsy;
+ int dumprect_size[2];
+
+ wmWindowManager *wm = CTX_wm_manager(C);
+ wmWindow *win = CTX_wm_window(C);
/* do redraw so we don't show popups/menus */
WM_redraw_windows(C);
- dumprect = screenshot(C, &dumpsx, &dumpsy);
+ uint *dumprect = WM_window_pixels_read(wm, win, dumprect_size);
if (dumprect) {
ScreenshotData *scd = MEM_callocN(sizeof(ScreenshotData), "screenshot");
ScrArea *sa = CTX_wm_area(C);
- scd->dumpsx = dumpsx;
- scd->dumpsy = dumpsy;
+ scd->dumpsx = dumprect_size[0];
+ scd->dumpsy = dumprect_size[1];
scd->dumprect = dumprect;
if (sa) {
scd->crop = sa->totrct;
diff --git a/source/blender/windowmanager/WM_api.h b/source/blender/windowmanager/WM_api.h
index 61b3b8aa2a2..d4fbbd1ecff 100644
--- a/source/blender/windowmanager/WM_api.h
+++ b/source/blender/windowmanager/WM_api.h
@@ -105,6 +105,8 @@ void WM_init_opengl(struct Main *bmain);
void WM_check(struct bContext *C);
void WM_reinit_gizmomap_all(struct Main *bmain);
+uint *WM_window_pixels_read(struct wmWindowManager *wm, struct wmWindow *win, int r_size[2]);
+
int WM_window_pixels_x(const struct wmWindow *win);
int WM_window_pixels_y(const struct wmWindow *win);
void WM_window_rect_calc(const struct wmWindow *win, struct rcti *r_rect);
diff --git a/source/blender/windowmanager/intern/wm_window.c b/source/blender/windowmanager/intern/wm_window.c
index 7558468c3b5..ea3596a2143 100644
--- a/source/blender/windowmanager/intern/wm_window.c
+++ b/source/blender/windowmanager/intern/wm_window.c
@@ -1937,6 +1937,50 @@ bool wm_window_get_swap_interval(wmWindow *win, int *intervalOut)
/** \} */
/* -------------------------------------------------------------------- */
+/** \name Window Screen Shot Utility
+ *
+ * Include here since it can involve low level buffer switching.
+ *
+ * \{ */
+
+uint *WM_window_pixels_read(wmWindowManager *wm, wmWindow *win, int r_size[2])
+{
+ bool setup_context = wm->windrawable != win;
+
+ if (setup_context) {
+ GHOST_ActivateWindowDrawingContext(win->ghostwin);
+ GPU_context_active_set(win->gpuctx);
+ }
+
+ r_size[0] = WM_window_pixels_x(win);
+ r_size[1] = WM_window_pixels_y(win);
+ const uint rect_len = r_size[0] * r_size[1];
+ uint *rect = MEM_mallocN(sizeof(*rect) * rect_len, __func__);
+
+ glReadBuffer(GL_FRONT);
+ glReadPixels(0, 0, r_size[0], r_size[1], GL_RGBA, GL_UNSIGNED_BYTE, rect);
+ glFinish();
+ glReadBuffer(GL_BACK);
+
+ if (setup_context) {
+ if (wm->windrawable) {
+ GHOST_ActivateWindowDrawingContext(wm->windrawable->ghostwin);
+ GPU_context_active_set(wm->windrawable->gpuctx);
+ }
+ }
+
+ /* Clear alpha, it is not set to a meaningful value in OpenGL. */
+ uchar *cp = (uchar *)rect;
+ uint i;
+ for (i = 0, cp += 3; i < rect_len; i++, cp += 4) {
+ *cp = 0xff;
+ }
+ return (uint *)rect;
+}
+
+/** \} */
+
+/* -------------------------------------------------------------------- */
/** \name Initial Window State API
* \{ */