Index: source/blender/blenkernel/intern/packedFile.c =================================================================== --- source/blender/blenkernel/intern/packedFile.c (revision 16492) +++ source/blender/blenkernel/intern/packedFile.c (working copy) @@ -63,6 +63,8 @@ #include "BKE_packedFile.h" #include "BKE_bad_level_calls.h" /* <- waitcursor */ +#include "../../../source/blender/python/api2_2x/Blender_Trace.h" + int seekPackedFile(PackedFile * pf, int offset, int whence) { int oldseek = -1, seek = 0; @@ -565,6 +567,9 @@ BLI_splitdirstring(localname, fi); sprintf(localname, "//textures/%s", fi); + Blender_Trace( BT_UNPACK_PROGRESS + , "unpackImage: Unpacking file \"%s\" using method %d\n" , localname , how ); + newname = unpackFile(ima->name, localname, ima->packedfile, how); if (newname != NULL) { ret_value = RET_OK; Index: source/blender/blenlib/BLI_threads.h =================================================================== --- source/blender/blenlib/BLI_threads.h (revision 16492) +++ source/blender/blenlib/BLI_threads.h (working copy) @@ -31,10 +31,33 @@ #ifndef BLI_THREADS_H #define BLI_THREADS_H -/* one custom lock available now. can be extended */ -#define LOCK_IMAGE 0 -#define LOCK_CUSTOM1 1 +/* + Lock identifiers. + In the event that you need to change the number of locks, add + one before LOCK_LAST, and update the initializers for g_locks[] in + blender/source/blender/blenlib/intern/threads.c +*/ +enum + { LOCK_IMAGE + /* lock to keep render engine from accessing the frame + buffer from multiple threads simultaneously */ + + , LOCK_CUSTOM1 + /* lock to keep ... ? */ + + , LOCK_TRACE + /* lock to keep Blender_Trace patch from accessing + Python from multiple threads simultaneously */ + + , LOCK_MALLOC + + , LOCK_LAST + /* must be last, because it is used as the size + of the g_locks[] array. There is not actually + a lock associated with LOCK_LAST. */ + }; + /* for tables, button in UI, etc */ #define BLENDER_MAX_THREADS 8 Index: source/blender/blenlib/intern/threads.c =================================================================== --- source/blender/blenlib/intern/threads.c (revision 16492) +++ source/blender/blenlib/intern/threads.c (working copy) @@ -92,9 +92,12 @@ BLI_end_threads(&lb); ************************************************ */ -static pthread_mutex_t _malloc_lock = PTHREAD_MUTEX_INITIALIZER; -static pthread_mutex_t _image_lock = PTHREAD_MUTEX_INITIALIZER; -static pthread_mutex_t _custom1_lock = PTHREAD_MUTEX_INITIALIZER; +static pthread_mutex_t g_locks[ LOCK_LAST ] = + { PTHREAD_MUTEX_INITIALIZER /* LOCK_IMAGE */ + , PTHREAD_MUTEX_INITIALIZER /* LOCK_CUSTOM1 */ + , PTHREAD_RECURSIVE_MUTEX_INITIALIZER /* LOCK_TRACE */ + , PTHREAD_MUTEX_INITIALIZER /* LOCK_MALLOC */ + /* LOCK_LAST - NO ENTRY HERE */ }; static int thread_levels= 0; /* threads can be invoked inside threads */ /* just a max for security reasons */ @@ -110,12 +113,12 @@ static void BLI_lock_malloc_thread(void) { - pthread_mutex_lock(&_malloc_lock); + BLI_lock_thread( LOCK_MALLOC ); } static void BLI_unlock_malloc_thread(void) { - pthread_mutex_unlock(&_malloc_lock); + BLI_unlock_thread( LOCK_MALLOC ); } /* tot = 0 only initializes malloc mutex in a safe way (see sequence.c) @@ -219,18 +222,12 @@ void BLI_lock_thread(int type) { - if (type==LOCK_IMAGE) - pthread_mutex_lock(&_image_lock); - else if (type==LOCK_CUSTOM1) - pthread_mutex_lock(&_custom1_lock); + pthread_mutex_lock( &g_locks[ type ] ); } void BLI_unlock_thread(int type) { - if (type==LOCK_IMAGE) - pthread_mutex_unlock(&_image_lock); - else if(type==LOCK_CUSTOM1) - pthread_mutex_unlock(&_custom1_lock); + pthread_mutex_unlock( &g_locks[ type ] ); } /* how many threads are native on this system? */ Index: source/blender/python/api2_2x/Blender.c =================================================================== --- source/blender/python/api2_2x/Blender.c (revision 16492) +++ source/blender/python/api2_2x/Blender.c (working copy) @@ -98,6 +98,8 @@ #include "Types.h" #include "Particle.h" +#include "Blender_Trace.h" + /**********************************************************/ /* Python API function prototypes for the Blender module. */ /**********************************************************/ @@ -315,6 +317,12 @@ U.gameflags |= USER_DISABLE_MIPMAP; GPU_set_mipmap(!(U.gameflags & USER_DISABLE_MIPMAP)); + } else if ( StringEqual( name , "traceCallback" ) ) { + return Set_Blender_Trace( self, args ); + } else if ( StringEqual( name , "traceFilterOn" ) ) { + return Set_Blender_Trace_Filter( self , arg , 1 ); + } else if ( StringEqual( name , "traceFilterOff" ) ) { + return Set_Blender_Trace_Filter( self , arg , 0 ); } else return ( EXPP_ReturnPyObjError( PyExc_AttributeError, "value given is not a blender setting" ) ); @@ -1022,6 +1030,7 @@ PyObject *module; PyObject *dict, *smode, *SpaceHandlers, *UnpackModes; + /* G.scene should only aver be NULL if blender is executed in background mode, not loading a blend file and executing a python script eg. blender -P somescript.py -b @@ -1061,7 +1070,7 @@ dict = PyModule_GetDict(module); g_blenderdict = dict; - PyModule_AddIntConstant(module, "TRUE", 1); + PyModule_AddIntConstant( module, "TRUE", 1); PyModule_AddIntConstant( module, "FALSE", 0 ); EXPP_dict_set_item_str(dict, "bylink", EXPP_incr_ret_False()); @@ -1109,4 +1118,6 @@ PyDict_SetItemString(dict, "Window", Window_Init()); PyDict_SetItemString(dict, "World", World_Init()); + Blender_Trace_Init( module ); } + Index: source/blender/python/api2_2x/blender_trace.c =================================================================== --- source/blender/python/api2_2x/blender_trace.c (revision 0) +++ source/blender/python/api2_2x/blender_trace.c (revision 0) @@ -0,0 +1,213 @@ +/* + * $Id: Blender_Trace.c $ + * + * ***** 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. + * All rights reserved. + * + * This is a new part of Blender. + * + * Contributor(s): Early Ehlinger + * + * ***** END GPL LICENSE BLOCK ***** +*/ +#include "Blender.h" /* This must come first */ +#include "Object.h" /* To tell Blender_Trace to include decls for PyObject* functions */ + +#include "Blender_Trace.h" + +#include +#include + +#include "BLI_threads.h" +#include "gen_utils.h" + +PyObject *g_blender_trace_callback = NULL; +uint8_t g_blender_trace_filter[ btfm_MAX ]; +uint8_t const g_blender_trace_filter_defaults[ btfm_MAX ] = + { 0 /* btfm_Debug */ + , 1 /* btfm_RenderProgress */ + , 1 /* btfm_UnpackProgress */ + , 1 /* btfm_FluidsProgress */ + , 1 /* btfm_Errors */ + /* btfm_MAX */ }; + +/*****************************************************************************/ +/* Function: Blender_Trace_Init */ +/* Purpose: */ +/* Initialize the Blender_Trace API. */ +/*****************************************************************************/ +void Blender_Trace_Init( PyObject *module ) +{ + BLI_lock_thread( LOCK_TRACE ); + if ( g_blender_trace_callback ) { + Py_XDECREF(g_blender_trace_callback); /* Dispose of callback */ + g_blender_trace_callback = NULL; + } + assert( btfm_Debug == 0 ); + memcpy( g_blender_trace_filter , g_blender_trace_filter_defaults , sizeof( g_blender_trace_filter ) ); + BLI_unlock_thread( LOCK_TRACE ); + + PyModule_AddIntConstant( module, "btfm_Debug" , btfm_Debug ); + PyModule_AddIntConstant( module, "btfm_RenderProgress" , btfm_RenderProgress ); + PyModule_AddIntConstant( module, "btfm_UnpackProgress" , btfm_UnpackProgress ); + PyModule_AddIntConstant( module, "btfm_FluidsProgress" , btfm_FluidsProgress ); + PyModule_AddIntConstant( module, "btfm_Errors" , btfm_Errors ); +} + + +/*****************************************************************************/ +/* Function: Blender_Trace */ +/* Purpose: */ +/* Calls into a python script that was previously registered with */ +/* Blender.Set( "traceCallback" , object ) */ +/* Essentially pilfered from http://docs.python.org/ext/callingPython.html */ +/* With a little sprintf magic from source/blender/src/toolbox.c */ +/*****************************************************************************/ +int Blender_Trace + ( blenderTraceFilterModes filterMode + , const char* fileName + , unsigned long lineNumber + , const char* format + , ... ) +{ + PyObject *arglist; + PyObject *result; + PyGILState_STATE gilstate; + + va_list ap; + char message[1024]; + int status = 0; + + /* Escape quickly if there is no callback or the user is filtering out this trace */ + if ( ( !g_blender_trace_callback ) + || ( 0 == g_blender_trace_filter[filterMode] ) ) + return status; + + /* format the message */ + va_start( ap, format ); + vsnprintf( message , sizeof( message ) , format , ap ); + va_end( ap ); + + BLI_lock_thread( LOCK_TRACE ); + + if ( g_blender_trace_callback && g_blender_trace_filter[ filterMode ] ) { + /* It may seem superfluous to perform this check, since we already performed + it just a few lines back. The reason for the additional check is that + it is conceivable that another thread could have modified the filter + or callback pointer after our initial "quick exit check" and before + we entered the LOCK_TRACE lock. */ + + /* Make a python argument list to pass to the traceCallback */ + arglist = Py_BuildValue("(s,i,s,i)" , fileName , lineNumber , message , filterMode ); + + /* Call the traceCallback function */ + //printf( "calling blender trace callback: %x\n" , g_blender_trace_callback ); + gilstate = PyGILState_Ensure(); + result = PyEval_CallObject(g_blender_trace_callback, arglist); + PyGILState_Release(gilstate); + + Py_DECREF(arglist); /* release the python argument list */ + + if(result){ + /*success*/ + Py_DECREF(result); + + } else { + /*handle error*/ + fprintf( stderr , "%s(%d) - There was an error tracing something\n" , __FILE__ , __LINE__ ); + status = 1; + } + } + + BLI_unlock_thread( LOCK_TRACE ); + return status; +} /* Blender_Trace */ + +/*****************************************************************************/ +/* Function: Set_Blender_Trace */ +/* Purpose: */ +/* Register a callback for use with Blender_Trace */ +/* Essentially pilfered from http://docs.python.org/ext/callingPython.html */ +/*****************************************************************************/ +PyObject* Set_Blender_Trace(PyObject *dummy, PyObject *args) +{ + PyObject* temp; + char* argname = NULL; + + if (PyArg_ParseTuple(args, "sO:traceCallback", &argname , &temp)) { + + if ( temp == Py_None ) { + Blender_Trace( BT_DEBUG , "Disconnecting traceCallback\n" ); + + BLI_lock_thread( LOCK_TRACE ); + + Py_XDECREF(g_blender_trace_callback); /* Dispose of previous callback */ + g_blender_trace_callback = NULL; + + BLI_unlock_thread( LOCK_TRACE ); + + Py_INCREF(Py_None); + return Py_None; + } + + if (!PyCallable_Check(temp)) { + PyErr_SetString(PyExc_TypeError, "traceCallback parameter must be callable"); + return NULL; + } + + BLI_lock_thread( LOCK_TRACE ); + Blender_Trace( BT_DEBUG , "Disconnecting old traceCallback (if any), Connecting new traceCallback\n" ); + Py_XINCREF(temp); /* Add a reference to new callback */ + Py_XDECREF(g_blender_trace_callback); /* Dispose of previous callback - Py_XDECREF is no-op when obj is NULL */ + g_blender_trace_callback = temp; /* Remember new callback */ + if ( Blender_Trace( BT_DEBUG , "Testing new traceCallback\n" ) ) { + fprintf( stderr , "%s(%d) - Failed to trace with new callback. Removing it.\n" , __FILE__ , __LINE__ ); + Py_XDECREF( g_blender_trace_callback ); + g_blender_trace_callback = NULL; + } + BLI_unlock_thread( LOCK_TRACE ); + + } + + /* Boilerplate to return "None" */ + Py_INCREF(Py_None); + return Py_None; +} /* Set_Blender_Trace */ + + +/*****************************************************************************/ +/* Function: Set_Blender_Trace_Filter */ +/* Purpose: */ +/* Change filter settings for Blender_Trace */ +/* Essentially pilfered from http://docs.python.org/ext/callingPython.html */ +/*****************************************************************************/ +PyObject* Set_Blender_Trace_Filter(PyObject *dummy, PyObject *arg , int on ) +{ + int new_filter = 0x0; + if ( !PyArg_Parse( arg , "i" , &new_filter )) + return EXPP_ReturnPyObjError( PyExc_ValueError, "expected an integer" ); + /* check for overflow */ + if ( new_filter < 0 || new_filter >= btfm_MAX ) + return EXPP_ReturnPyObjError( PyExc_ValueError, "index out of range" ); + BLI_lock_thread( LOCK_TRACE ); + g_blender_trace_filter[ new_filter ] = on; + BLI_unlock_thread( LOCK_TRACE ); + Py_INCREF(Py_None); + return Py_None; +} Property changes on: source/blender/python/api2_2x/blender_trace.c ___________________________________________________________________ Name: svn:executable + * Index: source/blender/python/api2_2x/blender_trace.h =================================================================== --- source/blender/python/api2_2x/blender_trace.h (revision 0) +++ source/blender/python/api2_2x/blender_trace.h (revision 0) @@ -0,0 +1,130 @@ +/* + * $Id: Blender.h,v 1.11 2005/07/18 03:50:36 ascotan Exp $ + * + * ***** BEGIN GPL/BL DUAL 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. The Blender + * Foundation also sells licenses for use in proprietary software under + * the Blender License. See http://www.blender.org/BL/ for information + * about this. + * + * 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + * + * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV. + * All rights reserved. + * + * This is a new part of Blender. + * + * Contributor(s): Early Ehlinger + * + * ***** END GPL/BL DUAL LICENSE BLOCK ***** +*/ + +#ifndef EXPP_BLENDER_TRACE_H +#define EXPP_BLENDER_TRACE_H + +#include "../../../blender/blenloader/BLO_sys_types.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/*****************************************************************************/ +/* Enum: blenderTraceFilterModes */ +/* Purpose: */ +/* Pass as filterMode to Blender_Trace. This value is used to index into */ +/* an array to determine if a particular message should be sent to the */ +/* python callback routine */ +/*****************************************************************************/ +typedef enum tag_blenderTraceFilterModes + { btfm_Debug = 0x00000000 + #define BT_DEBUG btfm_Debug , __FILE__ , __LINE__ + + , btfm_RenderProgress = 0x00000001 + #define BT_RENDER_PROGRESS btfm_RenderProgress , __FILE__ , __LINE__ + + , btfm_UnpackProgress = 0x00000002 + #define BT_UNPACK_PROGRESS btfm_RenderProgress , __FILE__ , __LINE__ + + + , btfm_FluidsProgress = 0x00000003 + #define BT_FLUIDS_PROGRESS btfm_RenderProgress , __FILE__ , __LINE__ + + , btfm_Errors = 0x00000004 + #define BT_ERRORS btfm_Errors , __FILE__ , __LINE__ + + , btfm_MAX /* must be the last one */ + } blenderTraceFilterModes; + +/*****************************************************************************/ +/* Function: Blender_Trace */ +/* Purpose: */ +/* Calls into a python script that was previously registered with */ +/* Blender.Set( "traceCallback" , object ) */ +/* */ +/* Basically, Blender_Trace generates a formatted string from the format */ +/* parameter and "...", and then passes it as sMessage to the */ +/* traceCallback. */ +/* */ +/* The python function should have this signature: */ +/* def traceCallback( fileName , lineNumber , sMessage ): */ +/* do_something_with( fileName , lineNumber , sMessage ); */ +/* */ +/* Parameters: */ +/* filterMode - - determines whether this trace is sent to */ +/* the python traceCallback function. */ +/* fileName - pass __FILE__ - should be the source file from which the */ +/* trace is coming. */ +/* lineNumber - pass __LINE__ - should be the line number from which the */ +/* trace is coming. */ +/* format - should be a sprintf-style format string */ +/* ... - should be sprintf-style arguments */ +/*****************************************************************************/ +int Blender_Trace( blenderTraceFilterModes filterMode + , const char* fileName + , unsigned long lineNumber + , const char* format + , ... ); + +/*****************************************************************************/ +/* Function: Set_Blender_Trace */ +/* Purpose: */ +/* Register a callback for use with Blender_Trace */ +/* Essentially pilfered from http://docs.python.org/ext/callingPython.html */ +/*****************************************************************************/ +#ifdef Py_OBJECT_H +PyObject* Set_Blender_Trace(PyObject *dummy, PyObject *args); +#endif + +/*****************************************************************************/ +/* Function: Set_Blender_Trace_Filter */ +/* Purpose: */ +/* Change filter settings for Blender_Trace */ +/*****************************************************************************/ +#ifdef Py_OBJECT_H +PyObject* Set_Blender_Trace_Filter(PyObject *dummy, PyObject *arg , int on ); + +/*****************************************************************************/ +/* Function: Blender_Trace_Init */ +/* Purpose: */ +/* Initialize the Blender_Trace API. */ +/*****************************************************************************/ +void Blender_Trace_Init( PyObject *module ); +#endif + + +#ifdef __cplusplus +} +#endif + +#endif Property changes on: source/blender/python/api2_2x/blender_trace.h ___________________________________________________________________ Name: svn:executable + * Index: source/blender/python/api2_2x/sceneRender.c =================================================================== --- source/blender/python/api2_2x/sceneRender.c (revision 16492) +++ source/blender/python/api2_2x/sceneRender.c (working copy) @@ -60,6 +60,8 @@ #include "Scene.h" #include "Group.h" +#include "blender_trace.h" + /* local defines */ #define PY_NONE 0 #define PY_LOW 1 @@ -473,6 +475,8 @@ /* unlock to prevent a deadlock when there are pynodes: */ PyThreadState *tstate = NULL; + Blender_Trace( BT_RENDER_PROGRESS , "RenderData_Render called" ); + if (!G.background) { oldsce = G.scene; set_scene( self->scene ); @@ -584,20 +588,34 @@ /* unlock to prevent a deadlock when there are pynodes: */ PyThreadState *tstate = NULL; + Blender_Trace( BT_RENDER_PROGRESS , "RenderData_RenderAnim called" ); + if (!G.background) { + Blender_Trace( BT_RENDER_PROGRESS , "RenderData_RenderAnim - !G.background path..." ); oldsce = G.scene; + + Blender_Trace( BT_RENDER_PROGRESS , "RenderData_RenderAnim - calling set_scene( self->scene )..." ); set_scene( self->scene ); tstate = PyEval_SaveThread(); + + Blender_Trace( BT_RENDER_PROGRESS , "RenderData_RenderAnim - calling BIF_do_render( 1 )..." ); BIF_do_render( 1 ); + + Blender_Trace( BT_RENDER_PROGRESS , "RenderData_RenderAnim - calling set_scene( oldsce )..." ); set_scene( oldsce ); } else { /* background mode (blender -b file.blend -P script) */ - Render *re= RE_NewRender(G.scene->id.name); + Render *re; + Blender_Trace( BT_RENDER_PROGRESS , "RenderData_RenderAnim - G.background path; calling RE_NewRender(\"render\")..." ); + re = RE_NewRender(G.scene->id.name); + + Blender_Trace( BT_RENDER_PROGRESS , "RenderData_RenderAnim - Checking for G.scene != self->scene..." ); if (G.scene != self->scene) return EXPP_ReturnPyObjError (PyExc_RuntimeError, "scene to render in bg mode must be the active scene"); + Blender_Trace( BT_RENDER_PROGRESS , "RenderData_RenderAnim - Checking for G.scene->r.sfra > G.scene->r.efra..." ); if (G.scene->r.sfra > G.scene->r.efra) return EXPP_ReturnPyObjError (PyExc_RuntimeError, "start frame must be less or equal to end frame"); @@ -606,11 +624,13 @@ BPY_do_all_scripts(SCRIPT_RENDER); tstate = PyEval_SaveThread(); + Blender_Trace( BT_RENDER_PROGRESS , "RenderData_RenderAnim - Calling RE_BlenderAnim" ); RE_BlenderAnim(re, G.scene, G.scene->r.sfra, G.scene->r.efra); if (G.f & G_DOSCRIPTLINKS) BPY_do_all_scripts(SCRIPT_POSTRENDER); } + Blender_Trace( BT_RENDER_PROGRESS , "RenderData_RenderAnim completed successfully." ); PyEval_RestoreThread(tstate); Py_RETURN_NONE; Index: source/blender/render/intern/source/initrender.c =================================================================== --- source/blender/render/intern/source/initrender.c (revision 16492) +++ source/blender/render/intern/source/initrender.c (working copy) @@ -80,6 +80,8 @@ #include "initrender.h" +#include "../../../source/blender/python/api2_2x/Blender_Trace.h" + /* ********************** */ static void init_render_jit(Render *re) @@ -634,6 +636,8 @@ rcti disprect; int rectx, recty; + Blender_Trace( BT_RENDER_PROGRESS , "initparts: part %d of %d" , nr , xparts * yparts ); + xd= (nr % xparts); yd= (nr-xd)/xparts; Index: source/blender/render/intern/source/pipeline.c =================================================================== --- source/blender/render/intern/source/pipeline.c (revision 16492) +++ source/blender/render/intern/source/pipeline.c (working copy) @@ -81,6 +81,7 @@ #include "pixelblending.h" #include "zbuf.h" +#include "../../../source/blender/python/api2_2x/Blender_Trace.h" /* render flow @@ -1247,6 +1248,11 @@ { RenderPart *pa= pa_v; + Blender_Trace + ( BT_RENDER_PROGRESS , "Rendering Tile [%d,%d]-[%d-%d]\n" + , pa->disprect.xmin , pa->disprect.ymin + , pa->disprect.xmax , pa->disprect.ymax ); + /* need to return nicely all parts on esc */ if(R.test_break()==0) { @@ -1284,6 +1290,8 @@ { RenderPart *pa; + Blender_Trace( BT_RENDER_PROGRESS , "render_tile_processor( ... )" ); + if(re->test_break()) return; @@ -1298,6 +1306,8 @@ if(re->result==NULL) return; + Blender_Trace( BT_RENDER_PROGRESS , "" ); + initparts(re); /* assuming no new data gets added to dbase... */ @@ -1479,6 +1489,8 @@ /* warning; no return here without closing exr file */ + Blender_Trace( BT_RENDER_PROGRESS , "" ); + initparts(re); if(re->result->exrhandle) { @@ -1918,9 +1930,15 @@ */ static void render_scene(Render *re, Scene *sce, int cfra) { - Render *resc= RE_NewRender(sce->id.name); - int winx= re->winx, winy= re->winy; + Render *resc; + int winx, winy; + Blender_Trace( BT_RENDER_PROGRESS , "render_scene called" ); + + resc= RE_NewRender(sce->id.name); + winx= re->winx; + winy= re->winy; + sce->r.cfra= cfra; /* exception: scene uses own size (unfinished code) */ @@ -2266,6 +2284,8 @@ /* main loop: doing sequence + fields + blur + 3d render + compositing */ static void do_render_all_options(Render *re) { + Blender_Trace( BT_RENDER_PROGRESS , "do_render_all_options() called" ); + re->i.starttime= PIL_check_seconds_timer(); /* ensure no images are in memory from previous animated sequences */ @@ -2419,6 +2439,8 @@ int winx, winy; rcti disprect; + Blender_Trace( BT_RENDER_PROGRESS , "render_initialize_from_scene called" ); + /* r.xsch and r.ysch has the actual view window size r.border is the clipping rect */ @@ -2473,6 +2495,10 @@ /* general Blender frame render call */ void RE_BlenderFrame(Render *re, Scene *scene, int frame) { + Blender_Trace( BT_RENDER_PROGRESS + , "RE_BlenderFrame(re=%x, scene=0x%x, frame= %d )" + , re , scene , frame ); + /* ugly global still... is to prevent renderwin events and signal subsurfs etc to make full resol */ /* is also set by caller renderwin.c */ G.rendering= 1; @@ -2561,8 +2587,15 @@ /* saves images to disk */ void RE_BlenderAnim(Render *re, Scene *scene, int sfra, int efra) { - bMovieHandle *mh= BKE_get_movie_handle(scene->r.imtype); - int cfrao= scene->r.cfra; + bMovieHandle *mh; + int cfrao; + + Blender_Trace( BT_RENDER_PROGRESS + , "RE_BlenderAnim(re=%x, scene=0x%x, sfra = %d , efra = %d )" + , re , scene , sfra , efra ); + + mh = BKE_get_movie_handle(scene->r.imtype); + cfrao = scene->r.cfra; /* do not fully call for each frame, it initializes & pops output window */ if(!render_initialize_from_scene(re, scene, 0)) Index: source/blender/render/intern/source/rendercore.c =================================================================== --- source/blender/render/intern/source/rendercore.c (revision 16492) +++ source/blender/render/intern/source/rendercore.c (working copy) @@ -76,6 +76,7 @@ /* own include */ #include "rendercore.h" +#include "../../../source/blender/python/api2_2x/Blender_Trace.h" /* ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ */ /* defined in pipeline.c, is hardcopy of active dynamic allocated Render */ @@ -771,21 +772,41 @@ int samp; int x, y, seed, crop=0, offs=0, od; - if(R.test_break()) return; + Blender_Trace( BT_RENDER_PROGRESS , "shadeDA_tile:\n" ); + Blender_Trace( BT_RENDER_PROGRESS , "shadeDA_tile: pa:%x\n" , pa ); + Blender_Trace( BT_RENDER_PROGRESS , "shadeDA_tile: rl:%x\n" , pa ); + rr= pa->result; + rectdaps= pa->rectdaps; + + if(R.test_break()) + { + Blender_Trace( BT_RENDER_PROGRESS , "shadeDA_tile: test_break() returns true. returning...\n" ); + return; + } /* irregular shadowb buffer creation */ if(R.r.mode & R_SHADOW) + { + Blender_Trace( BT_RENDER_PROGRESS , "shadeDA_tile: calling ISB_create()\n" ); ISB_create(pa, NULL); + Blender_Trace( BT_RENDER_PROGRESS , "shadeDA_tile: returned from ISB_create()\n" ); + } /* we set per pixel a fixed seed, for random AO and shadow samples */ seed= pa->rectx*pa->disprect.ymin; /* general shader info, passes */ + Blender_Trace( BT_RENDER_PROGRESS , "shadeDA_tile: calling shade_sample_initialize()\n" ); shade_sample_initialize(&ssamp, pa, rl); + Blender_Trace( BT_RENDER_PROGRESS , "shadeDA_tile: returned from shade_sample_initialize()\n" ); /* occlusion caching */ if(R.occlusiontree) + { + Blender_Trace( BT_RENDER_PROGRESS , "shadeDA_tile: calling cache_occ_samples()\n" ); cache_occ_samples(&R, pa, &ssamp); + Blender_Trace( BT_RENDER_PROGRESS , "shadeDA_tile: returned from cache_occ_samples()\n" ); + } /* filtered render, for now we assume only 1 filter size */ if(pa->crop) { @@ -803,6 +824,8 @@ rd= rectdaps; od= offs; + Blender_Trace( BT_RENDER_PROGRESS , "Scanline %d" , y ); + for(x=pa->disprect.xmin+crop; xdisprect.xmax-crop; x++, rd++, od++) { BLI_thread_srandom(pa->thread, seed++); @@ -835,6 +858,8 @@ if(y&1) if(R.test_break()) break; } + Blender_Trace( BT_RENDER_PROGRESS , "Scanline %d" , y ); + /* disable scanline updating */ rr->renlay= NULL; @@ -1127,6 +1152,7 @@ RenderLayer *rl; ListBase psmlist= {NULL, NULL}; float *edgerect= NULL; + int lyr = 0; /* allocate the necessary buffers */ /* zbuffer inits these rects */ @@ -1134,6 +1160,8 @@ pa->rectp= MEM_mallocN(sizeof(int)*pa->rectx*pa->recty, "rectp"); pa->rectz= MEM_mallocN(sizeof(int)*pa->rectx*pa->recty, "rectz"); for(rl= rr->layers.first; rl; rl= rl->next) { + Blender_Trace( BT_RENDER_PROGRESS , "Rendering layer %d\n" , ++lyr ); + if((rl->layflag & SCE_LAY_ZMASK) && (rl->layflag & SCE_LAY_NEG_ZMASK)) pa->rectmask= MEM_mallocN(sizeof(int)*pa->rectx*pa->recty, "rectmask"); @@ -1149,32 +1177,50 @@ for(pa->sample=0; pa->samplesample+=4) { ZbufSolidData sdata; + Blender_Trace( BT_RENDER_PROGRESS , "Rendering sample %d\n" , pa->sample ); + sdata.rl= rl; sdata.psmlist= &psmlist; sdata.edgerect= edgerect; + Blender_Trace( BT_RENDER_PROGRESS , "Calling zbuffer_solid()\n" ); zbuffer_solid(pa, rl, make_pixelstructs, &sdata); + Blender_Trace( BT_RENDER_PROGRESS , "Returned from zbuffer_solid()\n" ); if(R.test_break()) break; } /* shades solid */ if(rl->layflag & SCE_LAY_SOLID) + { + Blender_Trace( BT_RENDER_PROGRESS , "Calling shadeDA_tile()\n" ); shadeDA_tile(pa, rl); + Blender_Trace( BT_RENDER_PROGRESS , "Returned from shadeDA_tile()\n" ); + } /* lamphalo after solid, before ztra, looks nicest because ztra does own halo */ if(R.flag & R_LAMPHALO) if(rl->layflag & SCE_LAY_HALO) + { + Blender_Trace( BT_RENDER_PROGRESS , "Calling lamphalo_tile()\n" ); lamphalo_tile(pa, rl); + Blender_Trace( BT_RENDER_PROGRESS , "Returned from lamphalo_tile()\n" ); + } /* halo before ztra, because ztra fills in zbuffer now */ if(R.flag & R_HALO) if(rl->layflag & SCE_LAY_HALO) + { + Blender_Trace( BT_RENDER_PROGRESS , "Calling halo_tile()\n" ); halo_tile(pa, rl); + Blender_Trace( BT_RENDER_PROGRESS , "Returned from halo_tile()\n" ); + } /* transp layer */ if(R.flag & R_ZTRA || R.totstrand) { if(rl->layflag & (SCE_LAY_ZTRA|SCE_LAY_STRAND)) { if(pa->fullresult.first) { + Blender_Trace( BT_RENDER_PROGRESS , "Calling zbuffer_transp_shade()\n" ); zbuffer_transp_shade(pa, rl, rl->rectf, &psmlist); + Blender_Trace( BT_RENDER_PROGRESS , "Returned from zbuffer_transp_shade()\n" ); } else { unsigned short *ztramask, *solidmask= NULL; /* 16 bits, MAX_OSA */ @@ -1272,6 +1318,7 @@ RenderLayer *rl; PixStr ps; float *edgerect= NULL; + int lyr = 0; /* fake pixel struct, to comply to osa render */ ps.next= NULL; @@ -1283,6 +1330,8 @@ pa->rectz= MEM_mallocN(sizeof(int)*pa->rectx*pa->recty, "rectz"); for(rl= rr->layers.first; rl; rl= rl->next) { + Blender_Trace( BT_RENDER_PROGRESS , "Rendering layer %d\n" , ++lyr ); + if((rl->layflag & SCE_LAY_ZMASK) && (rl->layflag & SCE_LAY_NEG_ZMASK)) pa->rectmask= MEM_mallocN(sizeof(int)*pa->rectx*pa->recty, "rectmask"); @@ -1309,6 +1358,7 @@ float *fcol= rl->rectf; int *ro= pa->recto, *rp= pa->rectp, *rz= pa->rectz; int x, y, offs=0, seed; + int pnd = 0; /* we set per pixel a fixed seed, for random AO and shadow samples */ seed= pa->rectx*pa->disprect.ymin; @@ -1321,6 +1371,9 @@ cache_occ_samples(&R, pa, &ssamp); for(y=pa->disprect.ymin; ydisprect.ymax; y++, rr->renrect.ymax++) { + if ( ++pnd % 10 == 0 ) + Blender_Trace( BT_RENDER_PROGRESS , "#" ); + for(x=pa->disprect.xmin; xdisprect.xmax; x++, ro++, rz++, rp++, fcol+=4, offs++) { /* per pixel fixed seed */ BLI_thread_srandom(pa->thread, seed++); @@ -1338,6 +1391,7 @@ if(y&1) if(R.test_break()) break; } + Blender_Trace( BT_RENDER_PROGRESS , "#\n" ); if(R.occlusiontree) free_occ_samples(&R, pa); Index: source/blender/src/renderwin.c =================================================================== --- source/blender/src/renderwin.c (revision 16492) +++ source/blender/src/renderwin.c (working copy) @@ -106,6 +106,8 @@ #include "mydevice.h" #include "winlay.h" +#include "../../../source/blender/python/api2_2x/Blender_Trace.h" + /* ------------ renderwin struct, to prevent too much global vars --------- */ /* ------------ only used for display in a 2nd window --------- */ @@ -1098,30 +1100,51 @@ static void do_render(int anim) { Image *ima; - Render *re= RE_NewRender(G.scene->id.name); - unsigned int lay= G.scene->lay; - int scemode= G.scene->r.scemode; + Render *re; + unsigned int lay; + int scemode; int sculptmode= G.f & G_SCULPTMODE; + Blender_Trace( BT_RENDER_PROGRESS , "do_render( )" ); + Blender_Trace( BT_RENDER_PROGRESS , "do_render - G.scene = 0x%x" , G.scene ); + + re= RE_NewRender(G.scene->id.name); + lay= G.scene->lay; + scemode= G.scene->r.scemode; + /* UGLY! we set this flag to prevent renderwindow queue to execute another render */ /* is reset in RE_BlenderFrame */ G.rendering= 1; /* set render callbacks, also starts ESC timer */ + Blender_Trace( BT_RENDER_PROGRESS , "do_render - calling BIF_init_render_callbacks" ); BIF_init_render_callbacks(re, 1); + Blender_Trace( BT_RENDER_PROGRESS , "do_render - calling waitcursor(1)" ); waitcursor(1); if(render_win) + { + Blender_Trace( BT_RENDER_PROGRESS , "do_render - calling window_set_cursor(...)" ); window_set_cursor(render_win->win, CURSOR_WAIT); + } if(G.obedit) + { + Blender_Trace( BT_RENDER_PROGRESS , "do_render - calling exit_editmode()" ); exit_editmode(0); /* 0 = no free data */ + } - if(sculptmode) set_sculptmode(); + if(sculptmode) + { + Blender_Trace( BT_RENDER_PROGRESS , "do_render - calling set_sculpt_mode(...)" ); + set_sculptmode(); + } /* allow localview render for objects with lights in normal layers */ + Blender_Trace( BT_RENDER_PROGRESS , "do_render - allow localview render for objects with lights in normal layers" ); if(curarea->spacetype==SPACE_VIEW3D) { /* if view is defined (might not be if called from script), check and set layers. */ + Blender_Trace( BT_RENDER_PROGRESS , "do_render - G.vd = 0x%x" , G.vd ); if(G.vd) { if(G.vd->lay & 0xFF000000) { G.scene->lay |= G.vd->lay; @@ -1131,16 +1154,29 @@ } } + Blender_Trace( BT_RENDER_PROGRESS , "do_render - calling appropriate RE_BlenderXXX func" ); if(anim) + { + Blender_Trace( BT_RENDER_PROGRESS , "do_render - calling RE_BlenderAnim" ); RE_BlenderAnim(re, G.scene, G.scene->r.sfra, G.scene->r.efra); + } else + { + Blender_Trace( BT_RENDER_PROGRESS , "do_render - calling RE_BlenderFrame" ); RE_BlenderFrame(re, G.scene, G.scene->r.cfra); + } + Blender_Trace( BT_RENDER_PROGRESS , "do_render - RE_BlenderXXX func returned" ); /* restore local view exception */ G.scene->lay= lay; G.scene->r.scemode= scemode; - if(render_win) window_set_cursor(render_win->win, CURSOR_STD); + if(render_win) + { + Blender_Trace( BT_RENDER_PROGRESS , "do_render - resetting cursor" ); + window_set_cursor(render_win->win, CURSOR_STD); + } + Blender_Trace( BT_RENDER_PROGRESS , "do_render - cleaning up" ); free_filesel_spec(G.scene->r.pic); @@ -1161,6 +1197,7 @@ if(sculptmode) set_sculptmode(); waitcursor(0); + Blender_Trace( BT_RENDER_PROGRESS , "do_render - completed successfully" ); } /* called before render, store old render in spare buffer */ @@ -1276,7 +1313,9 @@ { int slink_flag = 0; + Blender_Trace( BT_RENDER_PROGRESS , "BIF_do_render( )" ); if (G.f & G_DOSCRIPTLINKS) { + Blender_Trace( BT_RENDER_PROGRESS , "BIF_do_render - calling BPY_do_all_scripts" ); BPY_do_all_scripts(SCRIPT_RENDER); if (!anim) { /* avoid FRAMECHANGED slink in render callback */ G.f &= ~G_DOSCRIPTLINKS; @@ -1284,18 +1323,25 @@ } } + Blender_Trace( BT_RENDER_PROGRESS , "BIF_do_render - calling BIF_store_spare" ); BIF_store_spare(); + Blender_Trace( BT_RENDER_PROGRESS , "BIF_do_render - calling do_render(anim)" ); do_render(anim); + Blender_Trace( BT_RENDER_PROGRESS , "BIF_do_render - checking G.scene->use_nodes" ); if(G.scene->use_nodes) { allqueue(REDRAWNODE, 1); allqueue(REDRAWIMAGE, 1); } + Blender_Trace( BT_RENDER_PROGRESS , "BIF_do_render - checking dither_intensity" ); if(G.scene->r.dither_intensity != 0.0f) BIF_redraw_render_rect(); + + Blender_Trace( BT_RENDER_PROGRESS , "BIF_do_render - finishing up" ); if (slink_flag) G.f |= G_DOSCRIPTLINKS; if (G.f & G_DOSCRIPTLINKS) BPY_do_all_scripts(SCRIPT_POSTRENDER); + Blender_Trace( BT_RENDER_PROGRESS , "BIF_do_render - done" ); } void do_ogl_view3d_render(Render *re, View3D *v3d, int winx, int winy) Index: source/blender/src/sequence.c =================================================================== --- source/blender/src/sequence.c (revision 16492) +++ source/blender/src/sequence.c (working copy) @@ -68,9 +68,12 @@ #include "blendef.h" +#include "../../../source/blender/python/api2_2x/Blender_Trace.h" + #include "BLI_threads.h" #include + #ifdef WIN32 #define snprintf _snprintf #endif @@ -2326,6 +2329,8 @@ ListBase *seqbasep; TStripElem *se; + Blender_Trace( BT_DEBUG , "" ); + ed= G.scene->ed; if(ed==0) return 0; @@ -2909,6 +2914,8 @@ { ImBuf *ibuf; + Blender_Trace( BT_RENDER_PROGRESS , "" ); + G.f |= G_PLAYANIM; /* waitcursor patch */ ibuf= give_ibuf_seq(rr->rectx, rr->recty, cfra, 0); Index: tools/test-blender-trace.py =================================================================== --- tools/test-blender-trace.py (revision 0) +++ tools/test-blender-trace.py (revision 0) @@ -0,0 +1,53 @@ +try: + + __author__ = "Early Ehlinger, ResPower, Inc" + __url__ = ("ResPower, Inc., http://www.respower.com") + __version__ = "1.2008.09.16" + + __bpydoc__ = """\ + This script just hooks up a BlenderTrace callback. Run it, then render, then + check out the console to see what happens. You may want to widen the console + to 120+ columns first, since this script prints the filename unchanged. + """ + + # -------------------------------------------------------------------------- + # + # Copyright (C) 2005, 2006, 2007, 2008 by ResPower, Inc + # ALL RIGHTS RESERVED + # + # -------------------------------------------------------------------------- + + import Blender + + print "[RPBC] ResPower Blender_Trace Test Script Version " + __version__; + + + import Blender + + def rpBlenderCallbackSvn( sFile , nLine , sMessage , nFilterMode ): + if ( sMessage == "#" ): + print sMessage, + else: + print "[RPBCB]" , sFile , "(" , nLine , ") - " , sMessage; + + print "[RPBC] Hooking up callback...\n"; + Blender.Set( "traceCallback" , rpBlenderCallbackSvn ); + print "[RPBC] ...Done.\n"; + + print "[RPBC] Setting up trace filter...\n"; + Blender.Set( "traceFilterOff" , Blender.btfm_Debug ); + print "[RPBC] ...Done.\n"; + + print "[RPBC] Setting up trace filter - turning off render progress...\n"; + Blender.Set( "traceFilterOff" , Blender.btfm_RenderProgress ); + print "[RPBC] ...Done.\n"; + + print "[RPBC] Setting up trace filter - turning on render progress...\n"; + Blender.Set( "traceFilterOn" , Blender.btfm_RenderProgress ); + print "[RPBC] ...Done.\n"; + +except Exception, inst: + print "Exception caught during test-blender-trace.py.\n"; + print type(inst) + print inst.args + print inst \ No newline at end of file Property changes on: tools/test-blender-trace.py ___________________________________________________________________ Name: svn:executable + *