Revision: 45528
          http://brlcad.svn.sourceforge.net/brlcad/?rev=45528&view=rev
Author:   kunigami
Date:     2011-07-18 20:13:20 +0000 (Mon, 18 Jul 2011)

Log Message:
-----------
added support to multi-thread using the OSL cocept of thread_info (hope I get 
it right :P) preliminary tests show a decrease in the time needed to render an 
example image when going from 1 to 2 processors 

Modified Paths:
--------------
    brlcad/trunk/src/liboptical/liboslrend.cpp
    brlcad/trunk/src/liboptical/liboslrend.h
    brlcad/trunk/src/liboptical/sh_osl.cpp

Modified: brlcad/trunk/src/liboptical/liboslrend.cpp
===================================================================
--- brlcad/trunk/src/liboptical/liboslrend.cpp  2011-07-18 17:27:32 UTC (rev 
45527)
+++ brlcad/trunk/src/liboptical/liboslrend.cpp  2011-07-18 20:13:20 UTC (rev 
45528)
@@ -31,8 +31,6 @@
     shadingsys = ShadingSystem::create(&rend, NULL, &errhandler);
     
     ssi = (ShadingSystemImpl *)shadingsys;
-    
-    handle = ssi->create_thread_info();
 }
 
 OSLRenderer::~OSLRenderer(){
@@ -101,7 +99,7 @@
     return sh_ref;
 }
 
-Color3 OSLRenderer::QueryColor(RenderInfo *info){
+Color3 OSLRenderer::QueryColor(RenderInfo *info) const {
 
     if(info->depth >= 5){
        return Color3(0.0f);
@@ -114,12 +112,9 @@
     Xi[1] = rand();
     Xi[2] = rand();
 
-    /* Thread specifics */
-    info->thread_info = handle;
-
     // execute shader
     ShaderGlobals globals;
-    const ClosureColor *closure = ExecuteShaders(globals, info, ssi);
+    const ClosureColor *closure = ExecuteShaders(globals, info);
 
     Color3 weight = Color3(0.0f);
     // sample primitive from closure tree
@@ -160,12 +155,18 @@
     }
     return Color3(0.0f);
 }
+/* Return thread specific information */
+void* OSLRenderer::CreateThreadInfo(){
+    return ssi->create_thread_info();
+}
+
+
 /* -----------------------------------------------
  * Private methods
  * ----------------------------------------------- */
 
 const ClosureColor * OSLRenderer::
-ExecuteShaders(ShaderGlobals &globals, RenderInfo *info, ShadingSystemImpl 
*ssi){
+ExecuteShaders(ShaderGlobals &globals, RenderInfo *info) const {
 
     memset(&globals, 0, sizeof(globals));
 
@@ -199,7 +200,7 @@
     return globals.Ci;
 }
 
-const ClosurePrimitive * OSLRenderer::SamplePrimitive(Color3& weight, const 
ClosureColor *closure, float r){
+const ClosurePrimitive * OSLRenderer::SamplePrimitive(Color3& weight, const 
ClosureColor *closure, float r) const {
 
     if(closure) {
        const ClosurePrimitive *prim = NULL;
@@ -213,7 +214,7 @@
     return NULL;
 }
 void OSLRenderer::SamplePrimitiveRecurse(const ClosurePrimitive*& r_prim, 
Color3& r_weight, const ClosureColor *closure,
-                                        const Color3& weight, float& totw, 
float& r){
+                                        const Color3& weight, float& totw, 
float& r) const {
 
     if(closure->type == ClosureColor::COMPONENT) {
 

Modified: brlcad/trunk/src/liboptical/liboslrend.h
===================================================================
--- brlcad/trunk/src/liboptical/liboslrend.h    2011-07-18 17:27:32 UTC (rev 
45527)
+++ brlcad/trunk/src/liboptical/liboslrend.h    2011-07-18 20:13:20 UTC (rev 
45528)
@@ -53,7 +53,7 @@
 struct RenderInfo {
 
     /* -- input -- */
-    void *thread_info;
+    void *thread_info;      /* Thread specific information */
     fastf_t screen_x;       /* Coordinates of the screen (if applicable) */
     fastf_t screen_y;
     point_t P;              /* Query point */
@@ -64,7 +64,7 @@
     int depth;              /* How many times the ray hit an object */
     fastf_t surfacearea;    /* FIXME */
     ShadingAttribStateRef shader_ref;   /* Reference for the shader we're 
querying */
-
+ 
     /* -- output -- */
     point_t pc;           /* Color of the point (or multiplier) */
     int doreflection;     /* 1 if there will be reflection 0, otherwise */
@@ -113,19 +113,19 @@
     std::vector<OSLShader> shaders;
 #endif
 
-    static const ClosureColor
-       *ExecuteShaders(ShaderGlobals &globals, RenderInfo *info, 
ShadingSystemImpl *ssi);
+    const ClosureColor
+       *ExecuteShaders(ShaderGlobals &globals, RenderInfo *info) const;
 
     /* Sample a primitive from the shaders group */
     const ClosurePrimitive* SamplePrimitive(Color3& weight,
                                            const ClosureColor *closure,
-                                           float r);
+                                           float r) const;
 
     /* Helper function for SamplePrimitive */
     void SamplePrimitiveRecurse(const ClosurePrimitive*& r_prim,
                                Color3& r_weight,
                                const ClosureColor *closure,
-                               const Color3& weight, float& totw, float& r);
+                               const Color3& weight, float& totw, float& r) 
const;
 
 public:
 
@@ -138,8 +138,11 @@
     ShadingAttribStateRef AddShader(ShaderGroupInfo &group_info);
 
     /* Query a color */
-    Color3 QueryColor(RenderInfo *info);
+    Color3 QueryColor(RenderInfo *info) const;
 
+    /* Return thread specific information */
+    void * CreateThreadInfo();
+
     static void Vec3toPoint_t(Vec3 s, point_t t){
        t[0] = s[0];
        t[1] = s[1];

Modified: brlcad/trunk/src/liboptical/sh_osl.cpp
===================================================================
--- brlcad/trunk/src/liboptical/sh_osl.cpp      2011-07-18 17:27:32 UTC (rev 
45527)
+++ brlcad/trunk/src/liboptical/sh_osl.cpp      2011-07-18 20:13:20 UTC (rev 
45528)
@@ -46,9 +46,17 @@
 /* Oslrenderer system */
 OSLRenderer *oslr = NULL;
 
+/* Every time a thread reaches osl_render for the first time,
+   we save the address of their own buffers, which is an ugly way to
+   identify them */
+std::vector<struct resource *> visited_addrs;
+/* Holds information about the context necessary to correctly execute a
+   shader */
+std::vector<void *> thread_infos;
+
 /* Save default a_hit */
-
 int (*default_a_hit)(struct application *, struct partition *, struct seg *);  
+/* Save default a_miss */
 int (*default_a_miss)(struct application *);   
 
 /*
@@ -339,14 +347,11 @@
      * -----------------------------------
      */
     /* If OSL system was not initialized yet, do it */
-    /* FIXME: take care of multi-thread issues */
-    bu_semaphore_acquire(BU_SEM_SYSCALL);
     if (oslr == NULL){
        oslr = new OSLRenderer();
     }
     /* Add this shader to OSL system */
-    osl_sp->shader_ref = oslr->AddShader(group_info);
-    bu_semaphore_release(BU_SEM_SYSCALL);
+    osl_sp->shader_ref = oslr->AddShader(group_info); 
 
     if (rdebug&RDEBUG_SHADE) {
        bu_struct_print(" Parameters:", osl_print_tab, (char *)osl_sp);
@@ -479,6 +484,8 @@
     register struct osl_specific *osl_sp =
        (struct osl_specific *)dp;
     
+    void * thread_info;
+
     /* check the validity of the arguments we got */
     RT_AP_CHECK(ap);
     RT_CHECK_PT(pp);
@@ -487,8 +494,25 @@
     if (rdebug&RDEBUG_SHADE)
        bu_struct_print("osl_render Parameters:", osl_print_tab,
                        (char *)osl_sp);
+
+    bu_semaphore_acquire(BU_SEM_SYSCALL);
     
-    bu_semaphore_acquire(BU_SEM_SYSCALL);
+    /* Check if it is the first time this thread is calling this function */
+    bool visited = false;
+    for(size_t i = 0; i < visited_addrs.size(); i++){
+       if(ap->a_resource == visited_addrs[i]){
+           visited = true;
+           thread_info = thread_infos[i];
+           break;
+       }
+    } 
+    if(!visited){
+       visited_addrs.push_back(ap->a_resource);
+       /* Get thread specific information from OSLRender system */
+       thread_info = oslr->CreateThreadInfo();
+       thread_infos.push_back(thread_info);
+    }
+
     if(ap->a_level == 0){
        default_a_hit = ap->a_hit; /* save the default hit callback (colorview 
@ rt) */
        default_a_miss = ap->a_miss;
@@ -527,10 +551,12 @@
 
     /* We only perform reflection if application decides to */
     info.doreflection = 0;
-    
-    bu_semaphore_acquire(BU_SEM_SYSCALL);
+
+    /* We assume that the only information that will be written is thread_info,
+       so that oslr->QueryColor is thread safe */
+    info.thread_info = thread_info;
+
     Color3 weight = oslr->QueryColor(&info);
-    bu_semaphore_release(BU_SEM_SYSCALL);
 
     /* Fire another ray */
     if(info.doreflection == 1){


This was sent by the SourceForge.net collaborative development platform, the 
world's largest Open Source development site.

------------------------------------------------------------------------------
Storage Efficiency Calculator
This modeling tool is based on patent-pending intellectual property that
has been used successfully in hundreds of IBM storage optimization engage-
ments, worldwide.  Store less, Store more with what you own, Move data to 
the right place. Try It Now! http://www.accelacomm.com/jaw/sfnl/114/51427378/
_______________________________________________
BRL-CAD Source Commits mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/brlcad-commits

Reply via email to