Browse Source

avoid async texload race condition

David Rose 17 years ago
parent
commit
d71d7a0fdb

+ 2 - 1
panda/src/display/graphicsStateGuardian.cxx

@@ -2240,6 +2240,7 @@ async_reload_texture(TextureContext *tc) {
   nassertv(_loader != (Loader *)NULL);
   nassertv(_loader != (Loader *)NULL);
 
 
   PT(AsyncTask) request = 
   PT(AsyncTask) request = 
-    new TextureReloadRequest(tc, _supports_compressed_texture);
+    new TextureReloadRequest(_prepared_objects, tc->get_texture(),
+                             _supports_compressed_texture);
   _loader->load_async(request);
   _loader->load_async(request);
 }
 }

+ 3 - 0
panda/src/gobj/Sources.pp

@@ -59,6 +59,7 @@
     texturePeeker.I texturePeeker.h \
     texturePeeker.I texturePeeker.h \
     texturePool.I texturePool.h \
     texturePool.I texturePool.h \
     texturePoolFilter.I texturePoolFilter.h \
     texturePoolFilter.I texturePoolFilter.h \
+    textureReloadRequest.I textureReloadRequest.h \
     textureStage.I textureStage.h \
     textureStage.I textureStage.h \
     transformBlend.I transformBlend.h \
     transformBlend.I transformBlend.h \
     transformBlendTable.I transformBlendTable.h \
     transformBlendTable.I transformBlendTable.h \
@@ -123,6 +124,7 @@
     texturePeeker.cxx \
     texturePeeker.cxx \
     texturePool.cxx \
     texturePool.cxx \
     texturePoolFilter.cxx \
     texturePoolFilter.cxx \
+    textureReloadRequest.cxx \
     textureStage.cxx \
     textureStage.cxx \
     transformBlend.cxx \
     transformBlend.cxx \
     transformBlendTable.cxx \
     transformBlendTable.cxx \
@@ -190,6 +192,7 @@
     texturePeeker.I texturePeeker.h \
     texturePeeker.I texturePeeker.h \
     texturePool.I texturePool.h \
     texturePool.I texturePool.h \
     texturePoolFilter.I texturePoolFilter.h \
     texturePoolFilter.I texturePoolFilter.h \
+    textureReloadRequest.I textureReloadRequest.h \
     textureStage.I textureStage.h \
     textureStage.I textureStage.h \
     transformBlend.I transformBlend.h \
     transformBlend.I transformBlend.h \
     transformBlendTable.I transformBlendTable.h \
     transformBlendTable.I transformBlendTable.h \

+ 12 - 0
panda/src/gobj/config_gobj.cxx

@@ -38,6 +38,7 @@
 #include "sliderTable.h"
 #include "sliderTable.h"
 #include "texture.h"
 #include "texture.h"
 #include "texturePoolFilter.h"
 #include "texturePoolFilter.h"
+#include "textureReloadRequest.h"
 #include "textureStage.h"
 #include "textureStage.h"
 #include "textureContext.h"
 #include "textureContext.h"
 #include "shader.h"
 #include "shader.h"
@@ -397,6 +398,16 @@ ConfigVariableInt adaptive_lru_max_updates_per_frame
  PRC_DESC("The number of pages the AdaptiveLru class will update per "
  PRC_DESC("The number of pages the AdaptiveLru class will update per "
           "frame.  Do not set this too high or it will degrade "
           "frame.  Do not set this too high or it will degrade "
           "performance."));
           "performance."));
+
+ConfigVariableDouble async_load_delay
+("async-load-delay", 0.0,
+PRC_DESC("If this is nonzero, it represents an artificial delay, "
+         "in seconds, that is imposed on every asynchronous load attempt "
+         "(within the thread).  Its purpose is to help debug errors that "
+         "may occur when an asynchronous load is delayed.  The "
+         "delay is per-model, and all aync loads will be queued "
+         "up behind the delay--it is as if the time it takes to read a "
+         "file is increased by this amount per read."));
  
  
 
 
 ConfigureFn(config_gobj) {
 ConfigureFn(config_gobj) {
@@ -435,6 +446,7 @@ ConfigureFn(config_gobj) {
   Texture::init_type();
   Texture::init_type();
   TextureContext::init_type();
   TextureContext::init_type();
   TexturePoolFilter::init_type();
   TexturePoolFilter::init_type();
+  TextureReloadRequest::init_type();
   TextureStage::init_type();
   TextureStage::init_type();
   TransformBlend::init_type();
   TransformBlend::init_type();
   TransformBlendTable::init_type();
   TransformBlendTable::init_type();

+ 1 - 0
panda/src/gobj/config_gobj.h

@@ -95,6 +95,7 @@ extern EXPCL_PANDA_GOBJ ConfigVariableInt vertex_data_page_threads;
 extern EXPCL_PANDA_GOBJ ConfigVariableInt graphics_memory_limit;
 extern EXPCL_PANDA_GOBJ ConfigVariableInt graphics_memory_limit;
 extern EXPCL_PANDA_GOBJ ConfigVariableDouble adaptive_lru_weight;
 extern EXPCL_PANDA_GOBJ ConfigVariableDouble adaptive_lru_weight;
 extern EXPCL_PANDA_GOBJ ConfigVariableInt adaptive_lru_max_updates_per_frame;
 extern EXPCL_PANDA_GOBJ ConfigVariableInt adaptive_lru_max_updates_per_frame;
+extern EXPCL_PANDA_GOBJ ConfigVariableDouble async_load_delay;
 
 
 #endif
 #endif
 
 

+ 1 - 0
panda/src/gobj/gobj_composite2.cxx

@@ -17,6 +17,7 @@
 #include "texturePeeker.cxx"
 #include "texturePeeker.cxx"
 #include "texturePool.cxx"
 #include "texturePool.cxx"
 #include "texturePoolFilter.cxx"
 #include "texturePoolFilter.cxx"
+#include "textureReloadRequest.cxx"
 #include "textureStage.cxx"
 #include "textureStage.cxx"
 #include "transformBlend.cxx"
 #include "transformBlend.cxx"
 #include "transformBlendTable.cxx"
 #include "transformBlendTable.cxx"

+ 3 - 2
panda/src/gobj/preparedGraphicsObjects.cxx

@@ -71,6 +71,7 @@ PreparedGraphicsObjects::
     TextureContext *tc = (*tci);
     TextureContext *tc = (*tci);
     tc->set_owning_chain(NULL);
     tc->set_owning_chain(NULL);
   }
   }
+  // Is this a leak?  Should we delete these TextureContexts?
   _released_textures.clear();
   _released_textures.clear();
 
 
   release_all_geoms();
   release_all_geoms();
@@ -213,7 +214,7 @@ void PreparedGraphicsObjects::
 release_texture(TextureContext *tc) {
 release_texture(TextureContext *tc) {
   ReMutexHolder holder(_lock);
   ReMutexHolder holder(_lock);
 
 
-  tc->get_texture()->clear_prepared(this);
+  tc->_texture->clear_prepared(this);
 
 
   // We have to set the Texture pointer to NULL at this point, since
   // We have to set the Texture pointer to NULL at this point, since
   // the Texture itself might destruct at any time after it has been
   // the Texture itself might destruct at any time after it has been
@@ -256,7 +257,7 @@ release_all_textures() {
        tci != _prepared_textures.end();
        tci != _prepared_textures.end();
        ++tci) {
        ++tci) {
     TextureContext *tc = (*tci);
     TextureContext *tc = (*tci);
-    tc->get_texture()->clear_prepared(this);
+    tc->_texture->clear_prepared(this);
     tc->_texture = (Texture *)NULL;
     tc->_texture = (Texture *)NULL;
 
 
     _released_textures.insert(tc);
     _released_textures.insert(tc);

+ 20 - 0
panda/src/gobj/texture.cxx

@@ -2010,6 +2010,26 @@ is_prepared(PreparedGraphicsObjects *prepared_objects) const {
   return prepared_objects->is_texture_queued(this);
   return prepared_objects->is_texture_queued(this);
 }
 }
 
 
+////////////////////////////////////////////////////////////////////
+//     Function: Texture::was_image_modified
+//       Access: Published
+//  Description: Returns true if the texture needs to be re-loaded
+//               onto the indicated GSG, either because its image data
+//               is out-of-date, or because it's not fully prepared
+//               now.
+////////////////////////////////////////////////////////////////////
+bool Texture::
+was_image_modified(PreparedGraphicsObjects *prepared_objects) const {
+  ReMutexHolder holder(_lock);
+  Contexts::const_iterator ci;
+  ci = _contexts.find(prepared_objects);
+  if (ci != _contexts.end()) {
+    TextureContext *tc = (*ci).second;
+    return tc->was_image_modified();
+  }
+  return true;
+}
+
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 //     Function: Texture::release
 //     Function: Texture::release
 //       Access: Published
 //       Access: Published

+ 1 - 0
panda/src/gobj/texture.h

@@ -346,6 +346,7 @@ PUBLISHED:
 
 
   void prepare(PreparedGraphicsObjects *prepared_objects);
   void prepare(PreparedGraphicsObjects *prepared_objects);
   bool is_prepared(PreparedGraphicsObjects *prepared_objects) const;
   bool is_prepared(PreparedGraphicsObjects *prepared_objects) const;
+  bool was_image_modified(PreparedGraphicsObjects *prepared_objects) const;
   bool release(PreparedGraphicsObjects *prepared_objects);
   bool release(PreparedGraphicsObjects *prepared_objects);
   int release_all();
   int release_all();
 
 

+ 22 - 9
panda/src/pgraph/textureReloadRequest.I → panda/src/gobj/textureReloadRequest.I

@@ -20,24 +20,37 @@
 //               via load_async(), to begin an asynchronous load.
 //               via load_async(), to begin an asynchronous load.
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 INLINE TextureReloadRequest::
 INLINE TextureReloadRequest::
-TextureReloadRequest(TextureContext *tc, bool allow_compressed) :
-  _texture_context(tc),
+TextureReloadRequest(PreparedGraphicsObjects *pgo, Texture *texture, 
+                     bool allow_compressed) :
+  _pgo(pgo),
+  _texture(texture),
   _allow_compressed(allow_compressed),
   _allow_compressed(allow_compressed),
   _is_ready(false)
   _is_ready(false)
 {
 {
-  nassertv(_texture_context != (TextureContext *)NULL);
-  _texture = _texture_context->get_texture();
+  nassertv(_pgo != (PreparedGraphicsObjects *)NULL);
+  nassertv(_texture != (Texture *)NULL);
 }
 }
 
 
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
-//     Function: TextureReloadRequest::get_texture_context
+//     Function: TextureReloadRequest::get_prepared_graphics_objects
 //       Access: Published
 //       Access: Published
-//  Description: Returns the TextureContext object associated with
+//  Description: Returns the PreparedGraphicsObjects object associated with
 //               this asynchronous TextureReloadRequest.
 //               this asynchronous TextureReloadRequest.
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
-INLINE TextureContext *TextureReloadRequest::
-get_texture_context() const {
-  return _texture_context;
+INLINE PreparedGraphicsObjects *TextureReloadRequest::
+get_prepared_graphics_objects() const {
+  return _pgo;
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: TextureReloadRequest::get_texture
+//       Access: Published
+//  Description: Returns the Texture object associated with
+//               this asynchronous TextureReloadRequest.
+////////////////////////////////////////////////////////////////////
+INLINE Texture *TextureReloadRequest::
+get_texture() const {
+  return _texture;
 }
 }
 
 
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////

+ 9 - 7
panda/src/pgraph/textureReloadRequest.cxx → panda/src/gobj/textureReloadRequest.cxx

@@ -13,7 +13,7 @@
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 
 
 #include "textureReloadRequest.h"
 #include "textureReloadRequest.h"
-#include "loader.h"
+#include "textureContext.h"
 
 
 TypeHandle TextureReloadRequest::_type_handle;
 TypeHandle TextureReloadRequest::_type_handle;
 
 
@@ -25,16 +25,18 @@ TypeHandle TextureReloadRequest::_type_handle;
 bool TextureReloadRequest::
 bool TextureReloadRequest::
 do_task() {
 do_task() {
   // Don't reload the texture if it doesn't need it.
   // Don't reload the texture if it doesn't need it.
-  if (_texture_context->was_image_modified()) {
+  if (_texture->was_image_modified(_pgo)) {
     double delay = async_load_delay;
     double delay = async_load_delay;
     if (delay != 0.0) {
     if (delay != 0.0) {
       Thread::sleep(delay);
       Thread::sleep(delay);
     }
     }
-
-    if (_allow_compressed) {
-      _texture->get_ram_image();
-    } else {
-      _texture->get_uncompressed_ram_image();
+    
+    if (_texture->was_image_modified(_pgo)) {
+      if (_allow_compressed) {
+        _texture->get_ram_image();
+      } else {
+        _texture->get_uncompressed_ram_image();
+      }
     }
     }
   }
   }
   _is_ready = true;
   _is_ready = true;

+ 9 - 6
panda/src/pgraph/textureReloadRequest.h → panda/src/gobj/textureReloadRequest.h

@@ -19,8 +19,9 @@
 
 
 #include "asyncTask.h"
 #include "asyncTask.h"
 #include "texture.h"
 #include "texture.h"
-#include "textureContext.h"
+#include "preparedGraphicsObjects.h"
 #include "pointerTo.h"
 #include "pointerTo.h"
+#include "pmutex.h"
 
 
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 //       Class : TextureReloadRequest
 //       Class : TextureReloadRequest
@@ -30,14 +31,16 @@
 //               used by GraphicsStateGuardian::async_reload_texture(),
 //               used by GraphicsStateGuardian::async_reload_texture(),
 //               when get_incomplete_render() is true.
 //               when get_incomplete_render() is true.
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
-class EXPCL_PANDA_PGRAPH TextureReloadRequest : public AsyncTask {
+class EXPCL_PANDA_GOBJ TextureReloadRequest : public AsyncTask {
 public:
 public:
   ALLOC_DELETED_CHAIN(TextureReloadRequest);
   ALLOC_DELETED_CHAIN(TextureReloadRequest);
 
 
 PUBLISHED:
 PUBLISHED:
-  INLINE TextureReloadRequest(TextureContext *tc, bool allow_compressed);
+  INLINE TextureReloadRequest(PreparedGraphicsObjects *pgo, Texture *texture,
+                              bool allow_compressed);
   
   
-  INLINE TextureContext *get_texture_context() const;
+  INLINE PreparedGraphicsObjects *get_prepared_graphics_objects() const;
+  INLINE Texture *get_texture() const;
   INLINE bool get_allow_compressed() const;
   INLINE bool get_allow_compressed() const;
   INLINE bool is_ready() const;
   INLINE bool is_ready() const;
   
   
@@ -45,9 +48,9 @@ protected:
   virtual bool do_task();
   virtual bool do_task();
   
   
 private:
 private:
-  TextureContext *_texture_context;
-  bool _allow_compressed;
+  PT(PreparedGraphicsObjects) _pgo;
   PT(Texture) _texture;
   PT(Texture) _texture;
+  bool _allow_compressed;
   bool _is_ready;
   bool _is_ready;
   
   
 public:
 public:

+ 0 - 3
panda/src/pgraph/Sources.pp

@@ -118,7 +118,6 @@
     textureAttrib.I textureAttrib.h \
     textureAttrib.I textureAttrib.h \
     texGenAttrib.I texGenAttrib.h \
     texGenAttrib.I texGenAttrib.h \
     textureCollection.I textureCollection.h \
     textureCollection.I textureCollection.h \
-    textureReloadRequest.I textureReloadRequest.h \
     textureStageCollection.I textureStageCollection.h \
     textureStageCollection.I textureStageCollection.h \
     transformState.I transformState.h \
     transformState.I transformState.h \
     transparencyAttrib.I transparencyAttrib.h \
     transparencyAttrib.I transparencyAttrib.h \
@@ -231,7 +230,6 @@
     textureAttrib.cxx \
     textureAttrib.cxx \
     texGenAttrib.cxx \
     texGenAttrib.cxx \
     textureCollection.cxx \
     textureCollection.cxx \
-    textureReloadRequest.cxx \
     textureStageCollection.cxx \
     textureStageCollection.cxx \
     transformState.cxx \
     transformState.cxx \
     transparencyAttrib.cxx \
     transparencyAttrib.cxx \
@@ -342,7 +340,6 @@
     textureAttrib.I textureAttrib.h \
     textureAttrib.I textureAttrib.h \
     texGenAttrib.I texGenAttrib.h \
     texGenAttrib.I texGenAttrib.h \
     textureCollection.I textureCollection.h \
     textureCollection.I textureCollection.h \
-    textureReloadRequest.I textureReloadRequest.h \
     textureStageCollection.I textureStageCollection.h \
     textureStageCollection.I textureStageCollection.h \
     transformState.I transformState.h \
     transformState.I transformState.h \
     transparencyAttrib.I transparencyAttrib.h \
     transparencyAttrib.I transparencyAttrib.h \

+ 0 - 12
panda/src/pgraph/config_pgraph.cxx

@@ -94,7 +94,6 @@
 #include "texMatrixAttrib.h"
 #include "texMatrixAttrib.h"
 #include "texProjectorEffect.h"
 #include "texProjectorEffect.h"
 #include "textureAttrib.h"
 #include "textureAttrib.h"
-#include "textureReloadRequest.h"
 #include "texGenAttrib.h"
 #include "texGenAttrib.h"
 #include "transformState.h"
 #include "transformState.h"
 #include "transparencyAttrib.h"
 #include "transparencyAttrib.h"
@@ -274,16 +273,6 @@ ConfigVariableBool flatten_geoms
           "only the NodePath interfaces; you may still make the lower-level "
           "only the NodePath interfaces; you may still make the lower-level "
           "SceneGraphReducer calls directly."));
           "SceneGraphReducer calls directly."));
 
 
-ConfigVariableDouble async_load_delay
-("async-load-delay", 0.0,
-PRC_DESC("If this is nonzero, it represents an artificial delay, "
-         "in seconds, that is imposed on every asynchronous load attempt "
-         "(within the thread).  Its purpose is to help debug errors that "
-         "may occur when an asynchronous load is delayed.  The "
-         "delay is per-model, and all aync loads will be queued "
-         "up behind the delay--it is as if the time it takes to read a "
-         "file is increased by this amount per read."));
-
 ConfigVariableBool polylight_info
 ConfigVariableBool polylight_info
 ("polylight-info", false,
 ("polylight-info", false,
  PRC_DESC("Set this true to view some info statements regarding the polylight. "
  PRC_DESC("Set this true to view some info statements regarding the polylight. "
@@ -460,7 +449,6 @@ init_libpgraph() {
   TexMatrixAttrib::init_type();
   TexMatrixAttrib::init_type();
   TexProjectorEffect::init_type();
   TexProjectorEffect::init_type();
   TextureAttrib::init_type();
   TextureAttrib::init_type();
-  TextureReloadRequest::init_type();
   TexGenAttrib::init_type();
   TexGenAttrib::init_type();
   TransformState::init_type();
   TransformState::init_type();
   TransparencyAttrib::init_type();
   TransparencyAttrib::init_type();

+ 0 - 1
panda/src/pgraph/config_pgraph.h

@@ -53,7 +53,6 @@ extern ConfigVariableInt max_collect_indices;
 extern ConfigVariableBool premunge_data;
 extern ConfigVariableBool premunge_data;
 extern ConfigVariableBool preserve_geom_nodes;
 extern ConfigVariableBool preserve_geom_nodes;
 extern ConfigVariableBool flatten_geoms;
 extern ConfigVariableBool flatten_geoms;
-extern ConfigVariableDouble async_load_delay;
 
 
 extern ConfigVariableBool polylight_info;
 extern ConfigVariableBool polylight_info;
 extern ConfigVariableDouble lod_fade_time;
 extern ConfigVariableDouble lod_fade_time;

+ 0 - 1
panda/src/pgraph/pgraph_composite4.cxx

@@ -25,7 +25,6 @@
 #include "textureAttrib.cxx"
 #include "textureAttrib.cxx"
 #include "texGenAttrib.cxx"
 #include "texGenAttrib.cxx"
 #include "textureCollection.cxx"
 #include "textureCollection.cxx"
-#include "textureReloadRequest.cxx"
 #include "textureStageCollection.cxx"
 #include "textureStageCollection.cxx"
 #include "transformState.cxx"
 #include "transformState.cxx"
 #include "transparencyAttrib.cxx"
 #include "transparencyAttrib.cxx"

+ 2 - 2
panda/src/tinydisplay/tinyGraphicsStateGuardian.cxx

@@ -765,13 +765,13 @@ begin_draw_primitives(const GeomPipelineReader *geom_reader,
   case AlphaTestAttrib::M_less:
   case AlphaTestAttrib::M_less:
   case AlphaTestAttrib::M_less_equal:
   case AlphaTestAttrib::M_less_equal:
     alpha_test_state = 1;    // aless
     alpha_test_state = 1;    // aless
-    _c->zb->reference_alpha = (int)_target._alpha_test->get_reference_alpha() * ZB_POINT_ALPHA_MAX;
+    _c->zb->reference_alpha = (int)(_target._alpha_test->get_reference_alpha() * ZB_POINT_ALPHA_MAX);
     break;
     break;
 
 
   case AlphaTestAttrib::M_greater:
   case AlphaTestAttrib::M_greater:
   case AlphaTestAttrib::M_greater_equal:
   case AlphaTestAttrib::M_greater_equal:
     alpha_test_state = 2;    // amore
     alpha_test_state = 2;    // amore
-    _c->zb->reference_alpha = (int)_target._alpha_test->get_reference_alpha() * ZB_POINT_ALPHA_MAX;
+    _c->zb->reference_alpha = (int)(_target._alpha_test->get_reference_alpha() * ZB_POINT_ALPHA_MAX);
     break;
     break;
   }
   }
 
 

+ 15 - 7
panda/src/tinydisplay/zbuffer.h

@@ -78,15 +78,23 @@ typedef unsigned int PIXEL;
 #define PSZB 4
 #define PSZB 4
 #define PSZSH 5
 #define PSZSH 5
 
 
-#define PIXEL_MULT(p1, p2) \
-  RGB_TO_PIXEL((PIXEL_R(p1) * PIXEL_R(p2)) >> 16, \
-               (PIXEL_G(p1) * PIXEL_G(p2)) >> 16, \
-               (PIXEL_B(p1) * PIXEL_B(p2)) >> 16)
+// Returns an unsigned product of c1 * c2
+#define PCOMPONENT_MULT(c1, c2) \
+  ((((unsigned int)(c1) * (unsigned int)(c2))) >> 16)
+
+// Returns a signed product of c1 * c2, where c1 is initially signed.
+// We leave 2 bits on the top to differentiate between c1 < 0 and c1 >
+// 0xffff; the result has the same sign.
+#define PALPHA_MULT(c1, c2) \
+  (((int)(((int)(c1) >> 2) * (unsigned int)(c2))) >> 14)
+
+#define PCOMPONENT_BLEND(c1, c2, a2) \
+  ((((unsigned int)(c1) * ((unsigned int)0xffff - (unsigned int)(a2)) + (unsigned int)(c2) * (unsigned int)(a2))) >> 16)
 
 
 #define PIXEL_BLEND(r1, g1, b1, r2, g2, b2, a2) \
 #define PIXEL_BLEND(r1, g1, b1, r2, g2, b2, a2) \
-  RGBA_TO_PIXEL(((r1) * (0xffff - (a2)) + (r2) * (a2)) >> 16,   \
-                ((g1) * (0xffff - (a2)) + (g2) * (a2)) >> 16,   \
-                ((b1) * (0xffff - (a2)) + (b2) * (a2)) >> 16,   \
+  RGBA_TO_PIXEL(PCOMPONENT_BLEND(r1, r2, a2),   \
+                PCOMPONENT_BLEND(g1, g2, a2),   \
+                PCOMPONENT_BLEND(b1, b2, a2),   \
                 a2)
                 a2)
 #define PIXEL_BLEND_RGB(rgb, r, g, b, a) \
 #define PIXEL_BLEND_RGB(rgb, r, g, b, a) \
   PIXEL_BLEND(PIXEL_R(rgb), PIXEL_G(rgb), PIXEL_B(rgb), r, g, b, a)
   PIXEL_BLEND(PIXEL_R(rgb), PIXEL_G(rgb), PIXEL_B(rgb), r, g, b, a)

+ 29 - 29
panda/src/tinydisplay/ztriangle_two.h

@@ -182,16 +182,16 @@ static void FNAME(flat_textured) (ZBuffer *zb,
     zz=z >> ZB_POINT_Z_FRAC_BITS;                                       \
     zz=z >> ZB_POINT_Z_FRAC_BITS;                                       \
     if (ZCMP(pz[_a], zz)) {                                             \
     if (ZCMP(pz[_a], zz)) {                                             \
       tmp = ZB_LOOKUP_TEXTURE(texture_levels, s, t, mipmap_level, mipmap_dx);      \
       tmp = ZB_LOOKUP_TEXTURE(texture_levels, s, t, mipmap_level, mipmap_dx);      \
-      int a = oa0 * PIXEL_A(tmp) >> 16;                                 \
+      int a = PALPHA_MULT(oa0, PIXEL_A(tmp));                           \
       if (ACMP(zb, a)) {                                                \
       if (ACMP(zb, a)) {                                                \
         STORE_PIX(pp[_a],                                               \
         STORE_PIX(pp[_a],                                               \
-                  RGBA_TO_PIXEL(or0 * PIXEL_R(tmp) >> 16,               \
-                                og0 * PIXEL_G(tmp) >> 16,               \
-                                ob0 * PIXEL_B(tmp) >> 16,               \
+                  RGBA_TO_PIXEL(PCOMPONENT_MULT(or0, PIXEL_R(tmp)),     \
+                                PCOMPONENT_MULT(og0, PIXEL_G(tmp)),     \
+                                PCOMPONENT_MULT(ob0, PIXEL_B(tmp)),     \
                                 a),                                     \
                                 a),                                     \
-                  or0 * PIXEL_R(tmp) >> 16,                             \
-                  og0 * PIXEL_G(tmp) >> 16,                             \
-                  ob0 * PIXEL_B(tmp) >> 16,                             \
+                  PCOMPONENT_MULT(or0, PIXEL_R(tmp)),                   \
+                  PCOMPONENT_MULT(og0, PIXEL_G(tmp)),                   \
+                  PCOMPONENT_MULT(ob0, PIXEL_B(tmp)),                   \
                   a);                                                   \
                   a);                                                   \
         STORE_Z(pz[_a], zz);                                            \
         STORE_Z(pz[_a], zz);                                            \
       }                                                                 \
       }                                                                 \
@@ -243,16 +243,16 @@ static void FNAME(smooth_textured) (ZBuffer *zb,
     zz=z >> ZB_POINT_Z_FRAC_BITS;                                       \
     zz=z >> ZB_POINT_Z_FRAC_BITS;                                       \
     if (ZCMP(pz[_a], zz)) {                                             \
     if (ZCMP(pz[_a], zz)) {                                             \
       tmp = ZB_LOOKUP_TEXTURE(texture_levels, s, t, mipmap_level, mipmap_dx);      \
       tmp = ZB_LOOKUP_TEXTURE(texture_levels, s, t, mipmap_level, mipmap_dx);      \
-      int a = oa1 * PIXEL_A(tmp) >> 16;                                 \
+      int a = PALPHA_MULT(oa1, PIXEL_A(tmp));                           \
       if (ACMP(zb, a)) {                                                \
       if (ACMP(zb, a)) {                                                \
         STORE_PIX(pp[_a],                                               \
         STORE_PIX(pp[_a],                                               \
-                  RGBA_TO_PIXEL(or1 * PIXEL_R(tmp) >> 16,               \
-                                og1 * PIXEL_G(tmp) >> 16,               \
-                                ob1 * PIXEL_B(tmp) >> 16,               \
+                  RGBA_TO_PIXEL(PCOMPONENT_MULT(or1, PIXEL_R(tmp)),     \
+                                PCOMPONENT_MULT(og1, PIXEL_G(tmp)),     \
+                                PCOMPONENT_MULT(ob1, PIXEL_B(tmp)),     \
                                 a),                                     \
                                 a),                                     \
-                  or1 * PIXEL_R(tmp) >> 16,                             \
-                  og1 * PIXEL_G(tmp) >> 16,                             \
-                  ob1 * PIXEL_B(tmp) >> 16,                             \
+                  PCOMPONENT_MULT(or1, PIXEL_R(tmp)),                   \
+                  PCOMPONENT_MULT(og1, PIXEL_G(tmp)),                   \
+                  PCOMPONENT_MULT(ob1, PIXEL_B(tmp)),                   \
                   a);                                                   \
                   a);                                                   \
         STORE_Z(pz[_a], zz);                                            \
         STORE_Z(pz[_a], zz);                                            \
       }                                                                 \
       }                                                                 \
@@ -422,16 +422,16 @@ static void FNAME(flat_perspective) (ZBuffer *zb,
     zz=z >> ZB_POINT_Z_FRAC_BITS;                                       \
     zz=z >> ZB_POINT_Z_FRAC_BITS;                                       \
     if (ZCMP(pz[_a], zz)) {                                             \
     if (ZCMP(pz[_a], zz)) {                                             \
       tmp = ZB_LOOKUP_TEXTURE(texture_levels, s, t, mipmap_level, mipmap_dx);      \
       tmp = ZB_LOOKUP_TEXTURE(texture_levels, s, t, mipmap_level, mipmap_dx);      \
-      int a = oa0 * PIXEL_A(tmp) >> 16;                                 \
+      int a = PALPHA_MULT(oa0, PIXEL_A(tmp));                           \
       if (ACMP(zb, a)) {                                                \
       if (ACMP(zb, a)) {                                                \
         STORE_PIX(pp[_a],                                               \
         STORE_PIX(pp[_a],                                               \
-                  RGBA_TO_PIXEL(or0 * PIXEL_R(tmp) >> 16,               \
-                                og0 * PIXEL_G(tmp) >> 16,               \
-                                ob0 * PIXEL_B(tmp) >> 16,               \
+                  RGBA_TO_PIXEL(PCOMPONENT_MULT(or0, PIXEL_R(tmp)),     \
+                                PCOMPONENT_MULT(og0, PIXEL_G(tmp)),     \
+                                PCOMPONENT_MULT(ob0, PIXEL_B(tmp)),     \
                                 a),                                     \
                                 a),                                     \
-                  or0 * PIXEL_R(tmp) >> 16,                             \
-                  og0 * PIXEL_G(tmp) >> 16,                             \
-                  ob0 * PIXEL_B(tmp) >> 16,                             \
+                  PCOMPONENT_MULT(or0, PIXEL_R(tmp)),                   \
+                  PCOMPONENT_MULT(og0, PIXEL_G(tmp)),                   \
+                  PCOMPONENT_MULT(ob0, PIXEL_B(tmp)),                   \
                   a);                                                   \
                   a);                                                   \
         STORE_Z(pz[_a], zz);                                            \
         STORE_Z(pz[_a], zz);                                            \
       }                                                                 \
       }                                                                 \
@@ -556,17 +556,17 @@ static void FNAME(smooth_perspective) (ZBuffer *zb,
   {                                                                     \
   {                                                                     \
     zz=z >> ZB_POINT_Z_FRAC_BITS;                                       \
     zz=z >> ZB_POINT_Z_FRAC_BITS;                                       \
     if (ZCMP(pz[_a], zz)) {                                             \
     if (ZCMP(pz[_a], zz)) {                                             \
-      tmp = ZB_LOOKUP_TEXTURE(texture_levels, s, t, mipmap_level, mipmap_dx);      \
-      int a = oa1 * PIXEL_A(tmp) >> 16;                                 \
+      tmp = ZB_LOOKUP_TEXTURE(texture_levels, s, t, mipmap_level, mipmap_dx); \
+      int a = PALPHA_MULT(oa1, PIXEL_A(tmp));                           \
       if (ACMP(zb, a)) {                                                \
       if (ACMP(zb, a)) {                                                \
         STORE_PIX(pp[_a],                                               \
         STORE_PIX(pp[_a],                                               \
-                  RGBA_TO_PIXEL(or1 * PIXEL_R(tmp) >> 16,               \
-                                og1 * PIXEL_G(tmp) >> 16,               \
-                                ob1 * PIXEL_B(tmp) >> 16,               \
+                  RGBA_TO_PIXEL(PCOMPONENT_MULT(or1, PIXEL_R(tmp)),     \
+                                PCOMPONENT_MULT(og1, PIXEL_G(tmp)),     \
+                                PCOMPONENT_MULT(ob1, PIXEL_B(tmp)),     \
                                 a),                                     \
                                 a),                                     \
-                  or1 * PIXEL_R(tmp) >> 16,                             \
-                  og1 * PIXEL_G(tmp) >> 16,                             \
-                  ob1 * PIXEL_B(tmp) >> 16,                             \
+                  PCOMPONENT_MULT(or1, PIXEL_R(tmp)),                   \
+                  PCOMPONENT_MULT(og1, PIXEL_G(tmp)),                   \
+                  PCOMPONENT_MULT(ob1, PIXEL_B(tmp)),                   \
                   a);                                                   \
                   a);                                                   \
         STORE_Z(pz[_a], zz);                                            \
         STORE_Z(pz[_a], zz);                                            \
       }                                                                 \
       }                                                                 \