Merge branch 'master' into blender2.8
authorSergey Sharybin <sergey.vfx@gmail.com>
Fri, 6 Jul 2018 15:16:23 +0000 (17:16 +0200)
committerSergey Sharybin <sergey.vfx@gmail.com>
Fri, 6 Jul 2018 15:16:23 +0000 (17:16 +0200)
1  2 
source/blender/windowmanager/intern/wm_playanim.c

index 8c062be2a000248c10ec010b98f3c9720f6a47aa,b4f2435ee2d982740a34e4461654415c2fcb5e47..ec9db1dd98e8f2478a2a9292178e3ab08c221017
  #include "IMB_imbuf_types.h"
  #include "IMB_imbuf.h"
  
 -#include "BKE_depsgraph.h"
  #include "BKE_image.h"
  
  #include "BIF_gl.h"
  #include "BIF_glutil.h"
  
 +#include "GPU_matrix.h"
 +#include "GPU_immediate.h"
 +#include "GPU_immediate_util.h"
 +#include "GPU_batch.h"
 +#include "GPU_init_exit.h"
 +
  #include "DNA_scene_types.h"
  #include "ED_datafiles.h" /* for fonts */
  #include "GHOST_C-api.h"
  #include "BLF_api.h"
  
 +#include "DEG_depsgraph.h"
 +
  #include "WM_api.h"  /* only for WM_main_playanim */
  
  #ifdef WITH_AUDASPACE
 -#  include AUD_DEVICE_H
 -#  include AUD_HANDLE_H
 -#  include AUD_SOUND_H
 -#  include AUD_SPECIAL_H
 +#  include <AUD_Device.h>
 +#  include <AUD_Handle.h>
 +#  include <AUD_Sound.h>
 +#  include <AUD_Special.h>
  
  static AUD_Sound *source = NULL;
  static AUD_Handle *playback_handle = NULL;
@@@ -139,6 -132,9 +139,9 @@@ typedef struct PlayState 
  
        /* restarts player for file drop */
        char dropped_file[FILE_MAX];
+       bool need_frame_update;
+       int frame_cursor_x;
  } PlayState;
  
  /* for debugging */
@@@ -181,7 -177,6 +184,7 @@@ typedef enum eWS_Qual 
  static struct WindowStateGlobal {
        GHOST_SystemHandle ghost_system;
        void *ghost_window;
 +      Gwn_Context *gwn_context;
  
        /* events */
        eWS_Qual qual;
@@@ -198,8 -193,10 +201,8 @@@ static void playanim_window_get_size(in
  static void playanim_gl_matrix(void)
  {
        /* unified matrix, note it affects offset for drawing */
 -      glMatrixMode(GL_PROJECTION);
 -      glLoadIdentity();
 -      glOrtho(0.0f, 1.0f, 0.0f, 1.0f, -1.0f, 1.0f);
 -      glMatrixMode(GL_MODELVIEW);
 +      /* note! cannot use gpuOrtho2D here because shader ignores. */
 +      gpuOrtho(0.0f, 1.0f, 0.0f, 1.0f, -1.0, 1.0f);
  }
  
  /* implementation */
@@@ -314,6 -311,7 +317,6 @@@ static void playanim_toscreen(PlayStat
  
        CLAMP(offs_x, 0.0f, 1.0f);
        CLAMP(offs_y, 0.0f, 1.0f);
 -      glRasterPos2f(offs_x, offs_y);
  
        glClearColor(0.1, 0.1, 0.1, 0.0);
        glClear(GL_COLOR_BUFFER_BIT);
        /* checkerboard for case alpha */
        if (ibuf->planes == 32) {
                glEnable(GL_BLEND);
 -              glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
 +              glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
  
 -              fdrawcheckerboard(offs_x, offs_y, offs_x + span_x, offs_y + span_y);
 +              imm_draw_box_checker_2d(offs_x, offs_y, offs_x + span_x, offs_y + span_y);
        }
  
 -      glRasterPos2f(offs_x + (ps->draw_flip[0] ? span_x : 0.0f),
 -                    offs_y + (ps->draw_flip[1] ? span_y : 0.0f));
 +      IMMDrawPixelsTexState state = immDrawPixelsTexSetup(GPU_SHADER_2D_IMAGE_COLOR);
  
 -      glPixelZoom(ps->zoom * (ps->draw_flip[0] ? -1.0f : 1.0f),
 -                  ps->zoom * (ps->draw_flip[1] ? -1.0f : 1.0f));
 -
 -      glDrawPixels(ibuf->x, ibuf->y, GL_RGBA, GL_UNSIGNED_BYTE, ibuf->rect);
 +      immDrawPixelsTex(
 +              &state,
 +              offs_x + (ps->draw_flip[0] ? span_x : 0.0f),
 +              offs_y + (ps->draw_flip[1] ? span_y : 0.0f),
 +              ibuf->x, ibuf->y, GL_RGBA, GL_UNSIGNED_BYTE, GL_NEAREST,
 +              ibuf->rect,
 +              ((ps->draw_flip[0] ? -1.0f : 1.0f)) * (ps->zoom / (float)ps->win_x),
 +              ((ps->draw_flip[1] ? -1.0f : 1.0f)) * (ps->zoom / (float)ps->win_y),
 +              NULL);
  
        glDisable(GL_BLEND);
  
                int sizex, sizey;
                float fsizex_inv, fsizey_inv;
                char str[32 + FILE_MAX];
 -              cpack(-1);
                BLI_snprintf(str, sizeof(str), "%s | %.2f frames/s", picture->name, fstep / swaptime);
  
                playanim_window_get_size(&sizex, &sizey);
                fsizex_inv = 1.0f / sizex;
                fsizey_inv = 1.0f / sizey;
  
 +              BLF_color4f(fontid, 1.0, 1.0, 1.0, 1.0);
                BLF_enable(fontid, BLF_ASPECT);
                BLF_aspect(fontid, fsizex_inv, fsizey_inv, 1.0f);
                BLF_position(fontid, 10.0f * fsizex_inv, 10.0f * fsizey_inv, 0.0f);
                float fac = ps->picture->frame / (double)(((PlayAnimPict *)picsbase.last)->frame - ((PlayAnimPict *)picsbase.first)->frame);
  
                fac = 2.0f * fac - 1.0f;
 -              glMatrixMode(GL_PROJECTION);
 -              glPushMatrix();
 -              glLoadIdentity();
 -              glMatrixMode(GL_MODELVIEW);
 -              glPushMatrix();
 -              glLoadIdentity();
 -
 -              glColor4f(0.0f, 1.0f, 0.0f, 1.0f);
 -
 -              glBegin(GL_LINES);
 -              glVertex2f(fac, -1.0f);
 -              glVertex2f(fac, 1.0f);
 -              glEnd();
 -
 -              glPopMatrix();
 -              glMatrixMode(GL_PROJECTION);
 -              glPopMatrix();
 -              glMatrixMode(GL_MODELVIEW);
 +              gpuPushProjectionMatrix();
 +              gpuLoadIdentityProjectionMatrix();
 +              gpuPushMatrix();
 +              gpuLoadIdentity();
 +
 +              unsigned int pos = GWN_vertformat_attr_add(immVertexFormat(), "pos", GWN_COMP_F32, 2, GWN_FETCH_FLOAT);
 +
 +              immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
 +              immUniformColor3ub(0, 255, 0);
 +
 +              immBegin(GWN_PRIM_LINES, 2);
 +              immVertex2f(pos, fac, -1.0f);
 +              immVertex2f(pos, fac,  1.0f);
 +              immEnd();
 +
 +              immUnbindProgram();
 +
 +              gpuPopMatrix();
 +              gpuPopProjectionMatrix();
        }
  
        GHOST_SwapWindowBuffers(g_WS.ghost_window);
@@@ -558,8 -551,18 +561,18 @@@ static void update_sound_fps(void
  #endif
  }
  
- static void change_frame(PlayState *ps, int cx)
+ static void tag_change_frame(PlayState *ps, int cx)
+ {
+       ps->need_frame_update = true;
+       ps->frame_cursor_x = cx;
+ }
+ static void change_frame(PlayState *ps)
  {
+       if (!ps->need_frame_update) {
+               return;
+       }
        int sizex, sizey;
        int i, i_last;
  
  
        playanim_window_get_size(&sizex, &sizey);
        i_last = ((struct PlayAnimPict *)picsbase.last)->frame;
-       i = (i_last * cx) / sizex;
+       i = (i_last * ps->frame_cursor_x) / sizex;
        CLAMP(i, 0, i_last);
  
  #ifdef WITH_AUDASPACE
        ps->sstep = true;
        ps->wait2 = false;
        ps->next_frame = 0;
+       ps->need_frame_update = false;
  }
  
  static int ghost_event_proc(GHOST_EventHandle evt, GHOST_TUserDataPtr ps_void)
                                if (type == GHOST_kEventButtonDown) {
                                        if (inside_window) {
                                                g_WS.qual |= WS_QUAL_LMOUSE;
-                                               change_frame(ps, cx);
+                                               tag_change_frame(ps, cx);
                                        }
                                }
                                else
  
                                GHOST_ScreenToClient(g_WS.ghost_window, cd->x, cd->y, &cx, &cy);
  
-                               change_frame(ps, cx);
+                               tag_change_frame(ps, cx);
                        }
                        break;
                }
@@@ -1265,10 -1270,6 +1280,10 @@@ static char *wm_main_playanim_intern(in
  
        //GHOST_ActivateWindowDrawingContext(g_WS.ghost_window);
  
 +      /* initialize OpenGL immediate mode */
 +      g_WS.gwn_context =  GWN_context_create();
 +      GPU_init();
 +
        /* initialize the font */
        BLF_init();
        ps.fontid = BLF_load_mem("monospace", (unsigned char *)datatoc_bmonofont_ttf, datatoc_bmonofont_ttf_size);
  
                        ps.next_frame = ps.direction;
  
-                       while ((hasevent = GHOST_ProcessEvents(g_WS.ghost_system, ps.wait2))) {
-                               if (hasevent) {
-                                       GHOST_DispatchEvents(g_WS.ghost_system);
-                               }
-                               /* Note, this still draws for mousemoves on pause */
-                               if (ps.wait2) {
-                                       if (hasevent) {
-                                               if (ibuf) {
-                                                       while (pupdate_time()) PIL_sleep_ms(1);
-                                                       ptottime -= swaptime;
-                                                       playanim_toscreen(&ps, ps.picture, ibuf, ps.fontid, ps.fstep);
-                                               }
-                                       }
-                               }
-                               if (ps.go == false) {
-                                       break;
-                               }
+                       while ((hasevent = GHOST_ProcessEvents(g_WS.ghost_system, 0))) {
+                               GHOST_DispatchEvents(g_WS.ghost_system);
+                       }
+                       if (ps.go == false) {
+                               break;
+                       }
+                       change_frame(&ps);
+                       if (!hasevent) {
+                               PIL_sleep_ms(1);
+                       }
+                       if (ps.wait2) {
+                               continue;
                        }
  
                        ps.wait2 = ps.sstep;
        /* we still miss freeing a lot!,
         * but many areas could skip initialization too for anim play */
  
 +      GPU_shader_free_builtin_shaders();
 +
 +      GPU_exit();
 +
 +      if (g_WS.gwn_context) {
 +              GWN_context_active_set(g_WS.gwn_context);
 +              GWN_context_discard(g_WS.gwn_context);
 +              g_WS.gwn_context = NULL;
 +      }
 +
        BLF_exit();
  
        GHOST_DisposeWindow(g_WS.ghost_system, g_WS.ghost_window);
  
        IMB_exit();
        BKE_images_exit();
 -      DAG_exit();
 +      DEG_free_node_types();
  
        totblock = MEM_get_memory_blocks_in_use();
        if (totblock != 0) {