better windows tau support; better threaded DeletedChain support; beginning PipelineReader classes

This commit is contained in:
David Rose
2006-04-20 04:03:16 +00:00
parent c567e620dd
commit 57338ee24d
94 changed files with 3634 additions and 1542 deletions
@@ -26,6 +26,7 @@
#include "dcFile.h"
#include "dcField.h" // to pick up Python.h
#include "pStatCollector.h"
#include "datagramIterator.h"
#ifdef HAVE_NSPR
#include "queuedConnectionManager.h"
@@ -279,6 +279,8 @@ finish_send_update(DCPacker &packer) {
nassertv(clock_delta != NULL);
double delta = PyFloat_AsDouble(clock_delta);
Py_DECREF(clock_delta);
#else
static const double delta = 0.0f;
#endif // HAVE_PYTHON
double local_time = ClockObject::get_global_clock()->get_frame_time();
+1 -1
View File
@@ -87,7 +87,7 @@
#push 1 $[file]_obj
#end file
#if $[USE_SINGLE_COMPOSITE_SOURCEFILE]
#if $[and $[not $[DONT_COMBINE]],$[or $[USE_SINGLE_COMPOSITE_SOURCEFILE],$[and $[USE_TAU],$[WINDOWS_PLATFORM]]]]
#if $[> $[words $[cxx_sources]], 1]
// If we have multiple C++ files, put them together into one
// composite file.
+1 -1
View File
@@ -121,7 +121,7 @@
// '#defer extra_cflags $[extra_cflags] /STUFF' will never work because extra_cflags hasnt been
// defined yet, so this just evaluates the reference to null and removes the reference and the
// the defining extra_cflags in individual sources.pp's will not picked up. use END_FLAGS instead
#defer extra_cflags /EHsc /Zm500 /DWIN32_VC /DWIN32 $[WARNING_LEVEL_FLAG] $[END_CFLAGS]
#defer extra_cflags /EHsc /Zm500 /DWIN32_VC /DWIN32=1 $[WARNING_LEVEL_FLAG] $[END_CFLAGS]
#if $[direct_tau]
#define tau_ipath $[TAU_ROOT]/include
+1 -1
View File
@@ -125,7 +125,7 @@
// '#defer extra_cflags $[extra_cflags] /STUFF' will never work because extra_cflags hasnt been
// defined yet, so this just evaluates the reference to null and removes the reference and the
// the defining extra_cflags in individual sources.pp's will not picked up. use END_FLAGS instead
#defer extra_cflags /EHsc /Zm300 /DWIN32_VC /DWIN32 $[WARNING_LEVEL_FLAG] $[END_CFLAGS]
#defer extra_cflags /EHsc /Zm300 /DWIN32_VC /DWIN32=1 $[WARNING_LEVEL_FLAG] $[END_CFLAGS]
#defer DECYGWINED_INC_PATHLIST_ARGS $[decygwin %,/I"%",$[EXTRA_INCPATH] $[ipath] $[WIN32_PLATFORMSDK_INCPATH]]
#defer MAIN_C_COMPILE_ARGS /nologo /c $[DECYGWINED_INC_PATHLIST_ARGS] $[flags] $[extra_cflags] "$[osfilename $[source]]"
+7
View File
@@ -183,7 +183,14 @@
/* ################################# DO NOT EDIT ########################### */
#foreach file $[$[composite_file]_sources]
#if $[USE_TAU]
// For the benefit of Tau, we copy the source file verbatim into the
// composite file. (Tau doesn't instrument files picked up via #include.)
#copy $[DIRPREFIX]$[file]
#else
##include "$[file]"
#endif // USE_TAU
#end file
#end $[composite_file]
+1 -1
View File
@@ -27,7 +27,7 @@
#include "atomicAdjustDummyImpl.h"
typedef AtomicAdjustDummyImpl AtomicAdjust;
#elif defined(__i386__) || defined(_M_IX86)
#elif defined(__i386__) || defined(_M_IX86)
// For an i386 architecture, we'll always use the i386 implementation.
// It should be safe for any OS, and it might be a bit faster than
// any OS-provided calls.
+42 -19
View File
@@ -17,9 +17,9 @@
////////////////////////////////////////////////////////////////////
template<class Type>
TYPENAME DeletedChain<Type>::ObjectNode *DeletedChain<Type>::_deleted_chain;
TVOLATILE TYPENAME DeletedChain<Type>::ObjectNode * TVOLATILE DeletedChain<Type>::_deleted_chain;
#ifndef HAVE_ATOMIC_COMPARE_AND_EXCHANGE_PTR
#ifndef DELETED_CHAIN_USE_ATOMIC_EXCHANGE
template<class Type>
MutexImpl DeletedChain<Type>::_lock;
#endif
@@ -35,38 +35,54 @@ allocate(size_t size) {
TAU_PROFILE("Type *DeletedChain<Type>::allocate(size_t)", " ", TAU_USER);
assert(size <= sizeof(Type));
#ifndef HAVE_ATOMIC_COMPARE_AND_EXCHANGE_PTR
TVOLATILE ObjectNode *obj;
#ifndef DELETED_CHAIN_USE_ATOMIC_EXCHANGE
_lock.lock();
if (_deleted_chain != (ObjectNode *)NULL) {
ObjectNode *obj = _deleted_chain;
obj = _deleted_chain;
_deleted_chain = _deleted_chain->_next;
_lock.release();
#ifndef NDEBUG
assert(obj->_flag == ((PN_int32)obj ^ deleted_chain_flag_hash));
obj->_flag = 0;
#endif // NDEBUG
return (Type *)obj;
}
_lock.release();
#else // HAVE_ATOMIC_COMPARE_AND_EXCHANGE_PTR
ObjectNode *obj = _deleted_chain;
#else // DELETED_CHAIN_USE_ATOMIC_EXCHANGE
obj = _deleted_chain;
while (obj != (ObjectNode *)NULL) {
ObjectNode *result = (ObjectNode *)AtomicAdjust::compare_and_exchange_ptr((void *&)_deleted_chain, (void *)obj, (void *)obj->_next);
TVOLATILE ObjectNode *next = obj->_next;
TVOLATILE ObjectNode *result = (ObjectNode *)AtomicAdjust::compare_and_exchange_ptr((void * TVOLATILE &)_deleted_chain, (void *)obj, (void *)next);
if (result == obj) {
// We got it.
#ifndef NDEBUG
assert(obj->_flag == ((PN_int32)obj ^ deleted_chain_flag_hash));
obj->_flag = 0;
#endif // NDEBUG
return (Type *)obj;
}
// Someone else grabbed the top link first. Try again.
obj = _deleted_chain;
}
#endif // HAVE_ATOMIC_COMPARE_AND_EXCHANGE_PTR
#endif // DELETED_CHAIN_USE_ATOMIC_EXCHANGE
// If we get here, the deleted_chain is empty; we have to allocate a
// new object from the system pool.
#ifdef DO_MEMORY_USAGE
return (Type *)(*global_operator_new)(sizeof(Type));
obj = (ObjectNode *)(*global_operator_new)(max(sizeof(Type), sizeof(ObjectNode)));
#else
return (Type *)malloc(sizeof(Type));
obj = (ObjectNode *)malloc(max(sizeof(Type), sizeof(ObjectNode)));
#endif
#ifndef NDEBUG
obj->_flag = 0;
#endif // NDEBUG
return (Type *)obj;
}
////////////////////////////////////////////////////////////////////
@@ -78,25 +94,32 @@ template<class Type>
INLINE void DeletedChain<Type>::
deallocate(Type *ptr) {
TAU_PROFILE("void DeletedChain<Type>::deallocate(Type *)", " ", TAU_USER);
#ifndef HAVE_ATOMIC_COMPARE_AND_EXCHANGE_PTR
TVOLATILE ObjectNode *obj = (ObjectNode *)ptr;
#ifndef NDEBUG
assert(obj->_flag != ((PN_int32)obj ^ deleted_chain_flag_hash));
obj->_flag = (PN_int32)obj ^ deleted_chain_flag_hash;
#endif // NDEBUG
#ifndef DELETED_CHAIN_USE_ATOMIC_EXCHANGE
_lock.lock();
ObjectNode *obj = (ObjectNode *)ptr;
obj->_next = _deleted_chain;
_deleted_chain = obj;
_lock.release();
#else // HAVE_ATOMIC_COMPARE_AND_EXCHANGE_PTR
#else // DELETED_CHAIN_USE_ATOMIC_EXCHANGE
ObjectNode *obj = (ObjectNode *)ptr;
ObjectNode *result;
TVOLATILE ObjectNode *result;
TVOLATILE ObjectNode *next;
do {
obj->_next = _deleted_chain;
result = (ObjectNode *)AtomicAdjust::compare_and_exchange_ptr((void *&)_deleted_chain, (void *)obj->_next, (void *)obj);
next = _deleted_chain;
obj->_next = next;
result = (ObjectNode *)AtomicAdjust::compare_and_exchange_ptr((void * TVOLATILE &)_deleted_chain, (void *)next, (void *)obj);
// Keep trying until no one else got to _deleted_chain first.
} while (result != obj->_next);
} while (result != next);
#endif // HAVE_ATOMIC_COMPARE_AND_EXCHANGE_PTR
#endif // DELETED_CHAIN_USE_ATOMIC_EXCHANGE
}
+19 -3
View File
@@ -23,8 +23,19 @@
#include "mutexImpl.h"
#include "atomicAdjust.h"
#include "numeric_types.h"
#include <assert.h>
#ifdef HAVE_ATOMIC_COMPARE_AND_EXCHANGE_PTR
// Actually, there appears to be a (maybe fatal) flaw in our
//implementation of DeletedChain via the atomic exchange operation.
//Specifically, a pointer may be removed from the head of the chain,
//then the same pointer reinserted in the chain, while another thread
//is waiting; and that thread will not detect the change. For now,
//then, let's not use this implmentation, and fall back to the mutex.
//#define DELETED_CHAIN_USE_ATOMIC_EXCHANGE
#endif
////////////////////////////////////////////////////////////////////
// Class : DeletedChain
// Description : This template class can be used to provide faster
@@ -60,7 +71,10 @@ public:
private:
class ObjectNode {
public:
ObjectNode *_next;
TVOLATILE ObjectNode * TVOLATILE _next;
#ifndef NDEBUG
TVOLATILE PN_int32 _flag;
#endif
};
// Ideally, the compiler and linker will unify all references to
@@ -68,15 +82,17 @@ private:
// However, if the compiler fails to do this (*cough* Microsoft), it
// won't be a big deal; it just means there will be multiple
// unrelated chains of deleted objects for a particular type.
static ObjectNode *_deleted_chain;
static TVOLATILE ObjectNode * TVOLATILE _deleted_chain;
#ifndef HAVE_ATOMIC_COMPARE_AND_EXCHANGE_PTR
#ifndef DELETED_CHAIN_USE_ATOMIC_EXCHANGE
// If we don't have atomic compare-and-exchange, we need to use a
// Mutex to protect the above linked list.
static MutexImpl _lock;
#endif
};
static const PN_int32 deleted_chain_flag_hash = 0x12345678;
// Place this macro within a class definition to define appropriate
// operator new and delete methods that take advantage of
// DeletedChain.
+6
View File
@@ -18,6 +18,12 @@
#include "dtoolbase.h"
#if defined(USE_TAU) && defined(WIN32)
// Hack around tau's lack of DLL export declarations for Profiler class.
bool __tau_shutdown = false;
#endif
/////////////////////////////////////////////////////////////////////
//
// Memory manager: DLMALLOC
+16 -5
View File
@@ -185,15 +185,18 @@ INLINE void operator delete[](void *ptr) {
#if defined(USE_TAU) && defined(WIN32)
// Hack around tau's lack of DLL export declarations for Profiler class.
extern EXPCL_DTOOL bool __tau_shutdown;
class EXPCL_DTOOL TauProfile {
public:
TauProfile(char *name, char *type, int group, char *group_name) {
_tautimer = NULL;
Tau_profile_c_timer(&_tautimer, name, type, group, group_name);
TauProfile(void *&tautimer, char *name, char *type, int group, char *group_name) {
Tau_profile_c_timer(&tautimer, name, type, group, group_name);
_tautimer = tautimer;
TAU_PROFILE_START(_tautimer);
}
~TauProfile() {
TAU_PROFILE_STOP(_tautimer);
if (!__tau_shutdown) {
TAU_PROFILE_STOP(_tautimer);
}
}
private:
@@ -201,7 +204,15 @@ private:
};
#undef TAU_PROFILE
#define TAU_PROFILE(name, type, group) TauProfile _taupr(name, type, group, #group)
#define TAU_PROFILE(name, type, group) \
static void *__tautimer; \
TauProfile __taupr(__tautimer, name, type, group, #group)
#undef TAU_PROFILE_EXIT
#define TAU_PROFILE_EXIT(msg) \
__tau_shutdown = true; \
Tau_exit(msg);
#endif // USE_TAU
#endif // GLOBAL_OPERATOR_NEW_EXCEPTIONS
+2
View File
@@ -19,6 +19,8 @@
#ifndef NUMERIC_TYPES_H
#define NUMERIC_TYPES_H
#include "dtoolbase.h"
// This header file defines a number of typedefs that correspond to
// the various numeric types for unsigned and signed numbers of
// various widths.
+8 -3
View File
@@ -452,12 +452,17 @@ assert_failure(const char *expression, int line,
// doesn't seem to work properly either, since we don't seem to
// get a reliable stack trace.
// Guess we'll still have to force a segfault.
// The old reliable int 3 works (at least on an Intel platform) if
// you are already running within a debugger. But it doesn't
// offer to bring up a debugger otherwise.
// So we'll force a segfault, which works every time.
int *ptr = (int *)NULL;
*ptr = 1;
#else
#else // WIN32
abort();
#endif
#endif // WIN32
}
return true;
+15 -13
View File
@@ -88,7 +88,8 @@ GraphicsStateGuardian(const FrameBufferProperties &properties,
set_coordinate_system(get_default_coordinate_system());
_current_display_region = (DisplayRegion*)0L;
_data_reader = (GeomVertexDataPipelineReader *)NULL;
_current_display_region = (DisplayRegion*)NULL;
_current_stereo_channel = Lens::SC_mono;
_current_lens = (Lens *)NULL;
_projection_mat = TransformState::make_identity();
@@ -1253,12 +1254,13 @@ finish_decal() {
// are ok, false to abort this group of primitives.
////////////////////////////////////////////////////////////////////
bool GraphicsStateGuardian::
begin_draw_primitives(const Geom *geom, const GeomMunger *munger,
const GeomVertexData *data) {
begin_draw_primitives(const GeomPipelineReader *geom_reader,
const GeomMunger *munger,
const GeomVertexDataPipelineReader *data_reader) {
_munger = munger;
_vertex_data = data;
nassertr(geom->check_valid(data), false);
return _vertex_data->has_vertex();
_data_reader = data_reader;
nassertr(geom_reader->check_valid(data_reader), false);
return _data_reader->has_vertex();
}
////////////////////////////////////////////////////////////////////
@@ -1267,7 +1269,7 @@ begin_draw_primitives(const Geom *geom, const GeomMunger *munger,
// Description: Draws a series of disconnected triangles.
////////////////////////////////////////////////////////////////////
void GraphicsStateGuardian::
draw_triangles(const GeomTriangles *) {
draw_triangles(const GeomPrimitivePipelineReader *) {
}
////////////////////////////////////////////////////////////////////
@@ -1276,7 +1278,7 @@ draw_triangles(const GeomTriangles *) {
// Description: Draws a series of triangle strips.
////////////////////////////////////////////////////////////////////
void GraphicsStateGuardian::
draw_tristrips(const GeomTristrips *primitive) {
draw_tristrips(const GeomPrimitivePipelineReader *) {
}
////////////////////////////////////////////////////////////////////
@@ -1285,7 +1287,7 @@ draw_tristrips(const GeomTristrips *primitive) {
// Description: Draws a series of triangle fans.
////////////////////////////////////////////////////////////////////
void GraphicsStateGuardian::
draw_trifans(const GeomTrifans *primitive) {
draw_trifans(const GeomPrimitivePipelineReader *) {
}
////////////////////////////////////////////////////////////////////
@@ -1294,7 +1296,7 @@ draw_trifans(const GeomTrifans *primitive) {
// Description: Draws a series of disconnected line segments.
////////////////////////////////////////////////////////////////////
void GraphicsStateGuardian::
draw_lines(const GeomLines *) {
draw_lines(const GeomPrimitivePipelineReader *) {
}
////////////////////////////////////////////////////////////////////
@@ -1303,7 +1305,7 @@ draw_lines(const GeomLines *) {
// Description: Draws a series of line strips.
////////////////////////////////////////////////////////////////////
void GraphicsStateGuardian::
draw_linestrips(const GeomLinestrips *primitive) {
draw_linestrips(const GeomPrimitivePipelineReader *) {
}
////////////////////////////////////////////////////////////////////
@@ -1312,7 +1314,7 @@ draw_linestrips(const GeomLinestrips *primitive) {
// Description: Draws a series of disconnected points.
////////////////////////////////////////////////////////////////////
void GraphicsStateGuardian::
draw_points(const GeomPoints *) {
draw_points(const GeomPrimitivePipelineReader *) {
}
////////////////////////////////////////////////////////////////////
@@ -1325,7 +1327,7 @@ draw_points(const GeomPoints *) {
void GraphicsStateGuardian::
end_draw_primitives() {
_munger = NULL;
_vertex_data = NULL;
_data_reader = NULL;
}
////////////////////////////////////////////////////////////////////
+12 -9
View File
@@ -193,15 +193,15 @@ public:
virtual CPT(RenderState) begin_decal_base_second();
virtual void finish_decal();
virtual bool begin_draw_primitives(const Geom *geom,
virtual bool begin_draw_primitives(const GeomPipelineReader *geom_reader,
const GeomMunger *munger,
const GeomVertexData *vertex_data);
virtual void draw_triangles(const GeomTriangles *primitive);
virtual void draw_tristrips(const GeomTristrips *primitive);
virtual void draw_trifans(const GeomTrifans *primitive);
virtual void draw_lines(const GeomLines *primitive);
virtual void draw_linestrips(const GeomLinestrips *primitive);
virtual void draw_points(const GeomPoints *primitive);
const GeomVertexDataPipelineReader *data_reader);
virtual void draw_triangles(const GeomPrimitivePipelineReader *reader);
virtual void draw_tristrips(const GeomPrimitivePipelineReader *reader);
virtual void draw_trifans(const GeomPrimitivePipelineReader *reader);
virtual void draw_lines(const GeomPrimitivePipelineReader *reader);
virtual void draw_linestrips(const GeomPrimitivePipelineReader *reader);
virtual void draw_points(const GeomPrimitivePipelineReader *reader);
virtual void end_draw_primitives();
INLINE bool reset_if_new();
@@ -270,8 +270,11 @@ protected:
CPT(RenderState) _state_rs;
CPT(RenderState) _target_rs;
CPT(TransformState) _internal_transform;
// These are set by begin_draw_primitives(), and are only valid
// between begin_draw_primitives() and end_draw_primitives().
CPT(GeomMunger) _munger;
CPT(GeomVertexData) _vertex_data;
const GeomVertexDataPipelineReader *_data_reader;
unsigned int _color_write_mask;
Colorf _color_clear_value;
+2 -1
View File
@@ -23,6 +23,7 @@
#include "buffer.h"
#include "multifile.h"
#include "pointerTo.h"
#include "vector_int.h"
////////////////////////////////////////////////////////////////////
// Class : Extractor
@@ -63,7 +64,7 @@ private:
Filename _extract_dir;
typedef pvector<int> Requests;
typedef vector_int Requests;
Requests _requests;
size_t _requests_total_length;
+1
View File
@@ -19,6 +19,7 @@
#include "filename.h"
#include "zStream.h"
#include "pnotify.h"
#include "config_util.h"
#ifndef HAVE_GETOPT
#include "gnu_getopt.h"
+116 -114
View File
@@ -788,24 +788,26 @@ end_frame() {
// are ok, false to abort this group of primitives.
////////////////////////////////////////////////////////////////////
bool DXGraphicsStateGuardian8::
begin_draw_primitives(const Geom *geom, const GeomMunger *munger,
const GeomVertexData *vertex_data) {
if (!GraphicsStateGuardian::begin_draw_primitives(geom, munger, vertex_data)) {
begin_draw_primitives(const GeomPipelineReader *geom_reader,
const GeomMunger *munger,
const GeomVertexDataPipelineReader *data_reader) {
if (!GraphicsStateGuardian::begin_draw_primitives(geom_reader, munger,
data_reader)) {
return false;
}
nassertr(_vertex_data != (GeomVertexData *)NULL, false);
nassertr(_data_reader != (GeomVertexDataPipelineReader *)NULL, false);
const GeomVertexFormat *format = _vertex_data->get_format();
const GeomVertexFormat *format = _data_reader->get_format();
// The munger should have put the FVF data in the first array.
const GeomVertexArrayData *data = _vertex_data->get_array(0);
const GeomVertexArrayDataPipelineReader *data = _data_reader->get_array_reader(0);
VertexBufferContext *vbc = ((GeomVertexArrayData *)data)->prepare_now(get_prepared_objects(), this);
VertexBufferContext *vbc = ((GeomVertexArrayData *)(data->get_object()))->prepare_now(get_prepared_objects(), this);
nassertr(vbc != (VertexBufferContext *)NULL, false);
apply_vertex_buffer(vbc);
const GeomVertexAnimationSpec &animation =
vertex_data->get_format()->get_animation();
data_reader->get_format()->get_animation();
if (animation.get_animation_type() == Geom::AT_hardware) {
// Set up vertex blending.
switch (animation.get_num_transforms()) {
@@ -836,7 +838,7 @@ begin_draw_primitives(const Geom *geom, const GeomMunger *munger,
_d3d_device->SetRenderState(D3DRS_INDEXEDVERTEXBLENDENABLE, FALSE);
}
const TransformTable *table = vertex_data->get_transform_table();
const TransformTable *table = data_reader->get_transform_table();
if (table != (TransformTable *)NULL) {
for (int i = 0; i < table->get_num_transforms(); i++) {
LMatrix4f mat;
@@ -859,14 +861,14 @@ begin_draw_primitives(const Geom *geom, const GeomMunger *munger,
_vertex_blending_enabled = false;
}
if (_transform_stale && !_vertex_data->is_vertex_transformed()) {
if (_transform_stale && !_data_reader->is_vertex_transformed()) {
const D3DMATRIX *d3d_mat = (const D3DMATRIX *)_internal_transform->get_mat().get_data();
_d3d_device->SetTransform(D3DTS_WORLD, d3d_mat);
_transform_stale = false;
}
}
if (_vertex_data->is_vertex_transformed()) {
if (_data_reader->is_vertex_transformed()) {
// If the vertex data claims to be already transformed into clip
// coordinates, wipe out the current projection and modelview
// matrix (so we don't attempt to transform it again).
@@ -895,53 +897,53 @@ begin_draw_primitives(const Geom *geom, const GeomMunger *munger,
// Description: Draws a series of disconnected triangles.
////////////////////////////////////////////////////////////////////
void DXGraphicsStateGuardian8::
draw_triangles(const GeomTriangles *primitive) {
draw_triangles(const GeomPrimitivePipelineReader *reader) {
PStatTimer timer(_draw_primitive_pcollector);
_vertices_tri_pcollector.add_level(primitive->get_num_vertices());
_vertices_tri_pcollector.add_level(reader->get_num_vertices());
_primitive_batches_tri_pcollector.add_level(1);
if (primitive->is_indexed()) {
int min_vertex = dx_broken_max_index ? 0 : primitive->get_min_vertex();
int max_vertex = primitive->get_max_vertex();
if (reader->is_indexed()) {
int min_vertex = dx_broken_max_index ? 0 : reader->get_min_vertex();
int max_vertex = reader->get_max_vertex();
if (_active_vbuffer != NULL) {
// Indexed, vbuffers.
IndexBufferContext *ibc = ((GeomPrimitive *)primitive)->prepare_now(get_prepared_objects(), this);
IndexBufferContext *ibc = ((GeomPrimitive *)(reader->get_object()))->prepare_now(get_prepared_objects(), this);
nassertv(ibc != (IndexBufferContext *)NULL);
apply_index_buffer(ibc);
_d3d_device->DrawIndexedPrimitive
(D3DPT_TRIANGLELIST,
min_vertex, max_vertex - min_vertex + 1,
0, primitive->get_num_primitives());
0, reader->get_num_primitives());
} else {
// Indexed, client arrays.
D3DFORMAT index_type = get_index_type(primitive->get_index_type());
D3DFORMAT index_type = get_index_type(reader->get_index_type());
draw_indexed_primitive_up
(D3DPT_TRIANGLELIST,
min_vertex, max_vertex,
primitive->get_num_primitives(),
primitive->get_data(),
reader->get_num_primitives(),
reader->get_data(),
index_type,
_vertex_data->get_array(0)->get_data(),
_vertex_data->get_format()->get_array(0)->get_stride());
_data_reader->get_array_reader(0)->get_data(),
_data_reader->get_format()->get_array(0)->get_stride());
}
} else {
if (_active_vbuffer != NULL) {
// Nonindexed, vbuffers.
_d3d_device->DrawPrimitive
(D3DPT_TRIANGLELIST,
primitive->get_first_vertex(),
primitive->get_num_primitives());
reader->get_first_vertex(),
reader->get_num_primitives());
} else {
// Nonindexed, client arrays.
draw_primitive_up(D3DPT_TRIANGLELIST, primitive->get_num_primitives(),
primitive->get_first_vertex(),
primitive->get_num_vertices(),
_vertex_data->get_array(0)->get_data(),
_vertex_data->get_format()->get_array(0)->get_stride());
draw_primitive_up(D3DPT_TRIANGLELIST, reader->get_num_primitives(),
reader->get_first_vertex(),
reader->get_num_vertices(),
_data_reader->get_array_reader(0)->get_data(),
_data_reader->get_format()->get_array(0)->get_stride());
}
}
}
@@ -952,77 +954,77 @@ draw_triangles(const GeomTriangles *primitive) {
// Description: Draws a series of triangle strips.
////////////////////////////////////////////////////////////////////
void DXGraphicsStateGuardian8::
draw_tristrips(const GeomTristrips *primitive) {
draw_tristrips(const GeomPrimitivePipelineReader *reader) {
PStatTimer timer(_draw_primitive_pcollector);
if (connect_triangle_strips && _current_fill_mode != RenderModeAttrib::M_wireframe) {
// One long triangle strip, connected by the degenerate vertices
// that have already been set up within the primitive.
_vertices_tristrip_pcollector.add_level(primitive->get_num_vertices());
_vertices_tristrip_pcollector.add_level(reader->get_num_vertices());
_primitive_batches_tristrip_pcollector.add_level(1);
if (primitive->is_indexed()) {
int min_vertex = dx_broken_max_index ? 0 : primitive->get_min_vertex();
int max_vertex = primitive->get_max_vertex();
if (reader->is_indexed()) {
int min_vertex = dx_broken_max_index ? 0 : reader->get_min_vertex();
int max_vertex = reader->get_max_vertex();
if (_active_vbuffer != NULL) {
// Indexed, vbuffers, one line triangle strip.
IndexBufferContext *ibc = ((GeomPrimitive *)primitive)->prepare_now(get_prepared_objects(), this);
IndexBufferContext *ibc = ((GeomPrimitive *)(reader->get_object()))->prepare_now(get_prepared_objects(), this);
nassertv(ibc != (IndexBufferContext *)NULL);
apply_index_buffer(ibc);
_d3d_device->DrawIndexedPrimitive
(D3DPT_TRIANGLESTRIP,
min_vertex, max_vertex - min_vertex + 1,
0, primitive->get_num_vertices() - 2);
0, reader->get_num_vertices() - 2);
} else {
// Indexed, client arrays, one long triangle strip.
D3DFORMAT index_type = get_index_type(primitive->get_index_type());
D3DFORMAT index_type = get_index_type(reader->get_index_type());
draw_indexed_primitive_up
(D3DPT_TRIANGLESTRIP,
min_vertex, max_vertex,
primitive->get_num_vertices() - 2,
primitive->get_data(), index_type,
_vertex_data->get_array(0)->get_data(),
_vertex_data->get_format()->get_array(0)->get_stride());
reader->get_num_vertices() - 2,
reader->get_data(), index_type,
_data_reader->get_array_reader(0)->get_data(),
_data_reader->get_format()->get_array(0)->get_stride());
}
} else {
if (_active_vbuffer != NULL) {
// Nonindexed, vbuffers, one long triangle strip.
_d3d_device->DrawPrimitive
(D3DPT_TRIANGLESTRIP,
primitive->get_first_vertex(),
primitive->get_num_vertices() - 2);
reader->get_first_vertex(),
reader->get_num_vertices() - 2);
} else {
// Indexed, client arrays, one long triangle strip.
draw_primitive_up(D3DPT_TRIANGLESTRIP,
primitive->get_num_vertices() - 2,
primitive->get_first_vertex(),
primitive->get_num_vertices(),
_vertex_data->get_array(0)->get_data(),
_vertex_data->get_format()->get_array(0)->get_stride());
reader->get_num_vertices() - 2,
reader->get_first_vertex(),
reader->get_num_vertices(),
_data_reader->get_array_reader(0)->get_data(),
_data_reader->get_format()->get_array(0)->get_stride());
}
}
} else {
// Send the individual triangle strips, stepping over the
// degenerate vertices.
CPTA_int ends = primitive->get_ends();
CPTA_int ends = reader->get_ends();
_primitive_batches_tristrip_pcollector.add_level(ends.size());
if (primitive->is_indexed()) {
CPTA_int ends = primitive->get_ends();
int index_stride = primitive->get_index_stride();
if (reader->is_indexed()) {
CPTA_int ends = reader->get_ends();
int index_stride = reader->get_index_stride();
_primitive_batches_tristrip_pcollector.add_level(ends.size());
GeomVertexReader mins(primitive->get_mins(), 0);
GeomVertexReader maxs(primitive->get_maxs(), 0);
nassertv(primitive->get_mins()->get_num_rows() == (int)ends.size() &&
primitive->get_maxs()->get_num_rows() == (int)ends.size());
GeomVertexReader mins(reader->get_mins(), 0);
GeomVertexReader maxs(reader->get_maxs(), 0);
nassertv(reader->get_mins()->get_num_rows() == (int)ends.size() &&
reader->get_maxs()->get_num_rows() == (int)ends.size());
if (_active_vbuffer != NULL) {
// Indexed, vbuffers, individual triangle strips.
IndexBufferContext *ibc = ((GeomPrimitive *)primitive)->prepare_now(get_prepared_objects(), this);
IndexBufferContext *ibc = ((GeomPrimitive *)(reader->get_object()))->prepare_now(get_prepared_objects(), this);
nassertv(ibc != (IndexBufferContext *)NULL);
apply_index_buffer(ibc);
@@ -1041,10 +1043,10 @@ draw_tristrips(const GeomTristrips *primitive) {
} else {
// Indexed, client arrays, individual triangle strips.
CPTA_uchar array_data = _vertex_data->get_array(0)->get_data();
int stride = _vertex_data->get_format()->get_array(0)->get_stride();
CPTA_uchar vertices = primitive->get_data();
D3DFORMAT index_type = get_index_type(primitive->get_index_type());
CPTA_uchar array_data = _data_reader->get_array_reader(0)->get_data();
int stride = _data_reader->get_format()->get_array(0)->get_stride();
CPTA_uchar vertices = reader->get_data();
D3DFORMAT index_type = get_index_type(reader->get_index_type());
unsigned int start = 0;
for (size_t i = 0; i < ends.size(); i++) {
@@ -1062,7 +1064,7 @@ draw_tristrips(const GeomTristrips *primitive) {
}
}
} else {
unsigned int first_vertex = primitive->get_first_vertex();
unsigned int first_vertex = reader->get_first_vertex();
if (_active_vbuffer != NULL) {
// Nonindexed, vbuffers, individual triangle strips.
@@ -1078,8 +1080,8 @@ draw_tristrips(const GeomTristrips *primitive) {
} else {
// Nonindexed, client arrays, individual triangle strips.
CPTA_uchar array_data = _vertex_data->get_array(0)->get_data();
int stride = _vertex_data->get_format()->get_array(0)->get_stride();
CPTA_uchar array_data = _data_reader->get_array_reader(0)->get_data();
int stride = _data_reader->get_format()->get_array(0)->get_stride();
unsigned int start = 0;
for (size_t i = 0; i < ends.size(); i++) {
@@ -1102,27 +1104,27 @@ draw_tristrips(const GeomTristrips *primitive) {
// Description: Draws a series of triangle fans.
////////////////////////////////////////////////////////////////////
void DXGraphicsStateGuardian8::
draw_trifans(const GeomTrifans *primitive) {
draw_trifans(const GeomPrimitivePipelineReader *reader) {
PStatTimer timer(_draw_primitive_pcollector);
CPTA_int ends = primitive->get_ends();
CPTA_int ends = reader->get_ends();
_primitive_batches_trifan_pcollector.add_level(ends.size());
if (primitive->is_indexed()) {
int min_vertex = dx_broken_max_index ? 0 : primitive->get_min_vertex();
int max_vertex = primitive->get_max_vertex();
if (reader->is_indexed()) {
int min_vertex = dx_broken_max_index ? 0 : reader->get_min_vertex();
int max_vertex = reader->get_max_vertex();
// Send the individual triangle fans. There's no connecting fans
// with degenerate vertices, so no worries about that.
int index_stride = primitive->get_index_stride();
int index_stride = reader->get_index_stride();
GeomVertexReader mins(primitive->get_mins(), 0);
GeomVertexReader maxs(primitive->get_maxs(), 0);
nassertv(primitive->get_mins()->get_num_rows() == (int)ends.size() &&
primitive->get_maxs()->get_num_rows() == (int)ends.size());
GeomVertexReader mins(reader->get_mins(), 0);
GeomVertexReader maxs(reader->get_maxs(), 0);
nassertv(reader->get_mins()->get_num_rows() == (int)ends.size() &&
reader->get_maxs()->get_num_rows() == (int)ends.size());
if (_active_vbuffer != NULL) {
// Indexed, vbuffers.
IndexBufferContext *ibc = ((GeomPrimitive *)primitive)->prepare_now(get_prepared_objects(), this);
IndexBufferContext *ibc = ((GeomPrimitive *)(reader->get_object()))->prepare_now(get_prepared_objects(), this);
nassertv(ibc != (IndexBufferContext *)NULL);
apply_index_buffer(ibc);
@@ -1141,10 +1143,10 @@ draw_trifans(const GeomTrifans *primitive) {
} else {
// Indexed, client arrays.
CPTA_uchar array_data = _vertex_data->get_array(0)->get_data();
int stride = _vertex_data->get_format()->get_array(0)->get_stride();
CPTA_uchar vertices = primitive->get_data();
D3DFORMAT index_type = get_index_type(primitive->get_index_type());
CPTA_uchar array_data = _data_reader->get_array_reader(0)->get_data();
int stride = _data_reader->get_format()->get_array(0)->get_stride();
CPTA_uchar vertices = reader->get_data();
D3DFORMAT index_type = get_index_type(reader->get_index_type());
unsigned int start = 0;
for (size_t i = 0; i < ends.size(); i++) {
@@ -1162,7 +1164,7 @@ draw_trifans(const GeomTrifans *primitive) {
}
}
} else {
unsigned int first_vertex = primitive->get_first_vertex();
unsigned int first_vertex = reader->get_first_vertex();
if (_active_vbuffer != NULL) {
// Nonindexed, vbuffers.
@@ -1178,8 +1180,8 @@ draw_trifans(const GeomTrifans *primitive) {
} else {
// Nonindexed, client arrays.
CPTA_uchar array_data = _vertex_data->get_array(0)->get_data();
int stride = _vertex_data->get_format()->get_array(0)->get_stride();
CPTA_uchar array_data = _data_reader->get_array_reader(0)->get_data();
int stride = _data_reader->get_format()->get_array(0)->get_stride();
unsigned int start = 0;
for (size_t i = 0; i < ends.size(); i++) {
@@ -1201,54 +1203,54 @@ draw_trifans(const GeomTrifans *primitive) {
// Description: Draws a series of disconnected line segments.
////////////////////////////////////////////////////////////////////
void DXGraphicsStateGuardian8::
draw_lines(const GeomLines *primitive) {
draw_lines(const GeomPrimitivePipelineReader *reader) {
PStatTimer timer(_draw_primitive_pcollector);
_vertices_other_pcollector.add_level(primitive->get_num_vertices());
_vertices_other_pcollector.add_level(reader->get_num_vertices());
_primitive_batches_other_pcollector.add_level(1);
if (primitive->is_indexed()) {
int min_vertex = dx_broken_max_index ? 0 : primitive->get_min_vertex();
int max_vertex = primitive->get_max_vertex();
if (reader->is_indexed()) {
int min_vertex = dx_broken_max_index ? 0 : reader->get_min_vertex();
int max_vertex = reader->get_max_vertex();
if (_active_vbuffer != NULL) {
// Indexed, vbuffers.
IndexBufferContext *ibc = ((GeomPrimitive *)primitive)->prepare_now(get_prepared_objects(), this);
IndexBufferContext *ibc = ((GeomPrimitive *)(reader->get_object()))->prepare_now(get_prepared_objects(), this);
nassertv(ibc != (IndexBufferContext *)NULL);
apply_index_buffer(ibc);
_d3d_device->DrawIndexedPrimitive
(D3DPT_LINELIST,
min_vertex, max_vertex - min_vertex + 1,
0, primitive->get_num_primitives());
0, reader->get_num_primitives());
} else {
// Indexed, client arrays.
D3DFORMAT index_type = get_index_type(primitive->get_index_type());
D3DFORMAT index_type = get_index_type(reader->get_index_type());
draw_indexed_primitive_up
(D3DPT_LINELIST,
min_vertex, max_vertex,
primitive->get_num_primitives(),
primitive->get_data(),
reader->get_num_primitives(),
reader->get_data(),
index_type,
_vertex_data->get_array(0)->get_data(),
_vertex_data->get_format()->get_array(0)->get_stride());
_data_reader->get_array_reader(0)->get_data(),
_data_reader->get_format()->get_array(0)->get_stride());
}
} else {
if (_active_vbuffer != NULL) {
// Nonindexed, vbuffers.
_d3d_device->DrawPrimitive
(D3DPT_LINELIST,
primitive->get_first_vertex(),
primitive->get_num_primitives());
reader->get_first_vertex(),
reader->get_num_primitives());
} else {
// Nonindexed, client arrays.
draw_primitive_up(D3DPT_LINELIST, primitive->get_num_primitives(),
primitive->get_first_vertex(),
primitive->get_num_vertices(),
_vertex_data->get_array(0)->get_data(),
_vertex_data->get_format()->get_array(0)->get_stride());
draw_primitive_up(D3DPT_LINELIST, reader->get_num_primitives(),
reader->get_first_vertex(),
reader->get_num_vertices(),
_data_reader->get_array_reader(0)->get_data(),
_data_reader->get_format()->get_array(0)->get_stride());
}
}
}
@@ -1259,7 +1261,7 @@ draw_lines(const GeomLines *primitive) {
// Description: Draws a series of line strips.
////////////////////////////////////////////////////////////////////
void DXGraphicsStateGuardian8::
draw_linestrips(const GeomLinestrips *primitive) {
draw_linestrips(const GeomPrimitivePipelineReader *reader) {
PStatTimer timer(_draw_primitive_pcollector);
}
@@ -1269,29 +1271,29 @@ draw_linestrips(const GeomLinestrips *primitive) {
// Description: Draws a series of disconnected points.
////////////////////////////////////////////////////////////////////
void DXGraphicsStateGuardian8::
draw_points(const GeomPoints *primitive) {
draw_points(const GeomPrimitivePipelineReader *reader) {
PStatTimer timer(_draw_primitive_pcollector);
_vertices_other_pcollector.add_level(primitive->get_num_vertices());
_vertices_other_pcollector.add_level(reader->get_num_vertices());
_primitive_batches_other_pcollector.add_level(1);
// The munger should have protected us from indexed points--DirectX
// doesn't support them.
nassertv(!primitive->is_indexed());
nassertv(!reader->is_indexed());
if (_active_vbuffer != NULL) {
// Nonindexed, vbuffers.
_d3d_device->DrawPrimitive
(D3DPT_POINTLIST,
primitive->get_first_vertex(),
primitive->get_num_primitives());
reader->get_first_vertex(),
reader->get_num_primitives());
} else {
// Nonindexed, client arrays.
draw_primitive_up(D3DPT_POINTLIST, primitive->get_num_primitives(),
primitive->get_first_vertex(),
primitive->get_num_vertices(),
_vertex_data->get_array(0)->get_data(),
_vertex_data->get_format()->get_array(0)->get_stride());
draw_primitive_up(D3DPT_POINTLIST, reader->get_num_primitives(),
reader->get_first_vertex(),
reader->get_num_vertices(),
_data_reader->get_array_reader(0)->get_data(),
_data_reader->get_format()->get_array(0)->get_stride());
}
}
@@ -1312,7 +1314,7 @@ end_draw_primitives() {
_vertex_blending_enabled = false;
}
if (_vertex_data->is_vertex_transformed()) {
if (_data_reader->is_vertex_transformed()) {
// Restore the projection matrix that we wiped out above.
_d3d_device->SetTransform(D3DTS_PROJECTION,
(D3DMATRIX*)_projection_mat->get_mat().get_data());
+8 -8
View File
@@ -75,15 +75,15 @@ public:
virtual void end_scene();
virtual void end_frame();
virtual bool begin_draw_primitives(const Geom *geom,
virtual bool begin_draw_primitives(const GeomPipelineReader *geom_reader,
const GeomMunger *munger,
const GeomVertexData *vertex_data);
virtual void draw_triangles(const GeomTriangles *primitive);
virtual void draw_tristrips(const GeomTristrips *primitive);
virtual void draw_trifans(const GeomTrifans *primitive);
virtual void draw_lines(const GeomLines *primitive);
virtual void draw_linestrips(const GeomLinestrips *primitive);
virtual void draw_points(const GeomPoints *primitive);
const GeomVertexDataPipelineReader *data_reader);
virtual void draw_triangles(const GeomPrimitivePipelineReader *reader);
virtual void draw_tristrips(const GeomPrimitivePipelineReader *reader);
virtual void draw_trifans(const GeomPrimitivePipelineReader *reader);
virtual void draw_lines(const GeomPrimitivePipelineReader *reader);
virtual void draw_linestrips(const GeomPrimitivePipelineReader *reader);
virtual void draw_points(const GeomPrimitivePipelineReader *reader);
virtual void end_draw_primitives();
virtual void framebuffer_copy_to_texture(Texture *tex, int z, const DisplayRegion *dr,
+127 -125
View File
@@ -1144,12 +1144,14 @@ DBG_S dxgsg9_cat.debug ( ) << "@@@@@@@@@@ end_frame \n"; DBG_E
// are ok, false to abort this group of primitives.
////////////////////////////////////////////////////////////////////
bool DXGraphicsStateGuardian9::
begin_draw_primitives(const Geom *geom, const GeomMunger *munger,
const GeomVertexData *vertex_data) {
if (!GraphicsStateGuardian::begin_draw_primitives(geom, munger, vertex_data)) {
begin_draw_primitives(const GeomPipelineReader *geom_reader,
const GeomMunger *munger,
const GeomVertexDataPipelineReader *data_reader) {
if (!GraphicsStateGuardian::begin_draw_primitives(geom_reader, munger,
data_reader)) {
return false;
}
nassertr(_vertex_data != (GeomVertexData *)NULL, false);
nassertr(_data_reader != (GeomVertexDataPipelineReader *)NULL, false);
DBG_SH5 dxgsg9_cat.debug ( ) << "begin_draw_primitives\n"; DBG_E
@@ -1173,9 +1175,9 @@ begin_draw_primitives(const Geom *geom, const GeomMunger *munger,
_vertex_array_shader_expansion = _current_shader_expansion;
_vertex_array_shader_context = _current_shader_context;
const GeomVertexFormat *format = _vertex_data->get_format ( );
const GeomVertexArrayData *data;
int number_of_arrays = _vertex_data -> get_num_arrays ( );
const GeomVertexFormat *format = _data_reader->get_format ( );
const GeomVertexArrayDataPipelineReader *data;
int number_of_arrays = _data_reader -> get_num_arrays ( );
if (_current_shader_context && number_of_arrays > 1) {
@@ -1198,7 +1200,7 @@ begin_draw_primitives(const Geom *geom, const GeomMunger *munger,
// find the one array with the minimum number of elements if possible
{
for (index = 0; index < number_of_arrays; index++) {
data = _vertex_data -> get_array (index);
data = _data_reader -> get_array_reader (index);
const GeomVertexArrayFormat *array_format = data->get_array_format();
int number_of_columns = array_format->get_num_columns();
@@ -1227,7 +1229,7 @@ begin_draw_primitives(const Geom *geom, const GeomMunger *munger,
// ugh slow, need to find which one
for (index = first_index; index < number_of_arrays; index++)
{
data = _vertex_data -> get_array (index);
data = _data_reader -> get_array_reader (index);
const GeomVertexArrayFormat *array_format = data->get_array_format();
int number_of_columns = array_format->get_num_columns();
@@ -1247,15 +1249,15 @@ vertex_element_array -> vertex_element_type_array;
}
}
// since the check is not implemented yet use first_index for now
data = _vertex_data -> get_array (first_index);
// since the check is not implemented yet use first_index for now
data = _data_reader -> get_array_reader (first_index);
match = true;
}
else
{
if (first_index >= 0) {
data = _vertex_data -> get_array (first_index);
data = _data_reader -> get_array_reader (first_index);
match = true;
}
}
@@ -1268,7 +1270,7 @@ data = _vertex_data -> get_array (first_index);
dxgsg9_cat.error ( ) << "could not find matching vertex element data for vertex shader\n";
// just use the 0 array
data = _vertex_data->get_array(0);
data = _data_reader->get_array_reader(0);
}
}
else {
@@ -1278,15 +1280,15 @@ data = _vertex_data -> get_array (first_index);
}
else {
// The munger should have put the FVF data in the first array.
data = _vertex_data->get_array(0);
data = _data_reader->get_array_reader(0);
}
VertexBufferContext *vbc = ((GeomVertexArrayData *)data)->prepare_now(get_prepared_objects(), this);
VertexBufferContext *vbc = ((GeomVertexArrayData *)(data->get_object()))->prepare_now(get_prepared_objects(), this);
nassertr(vbc != (VertexBufferContext *)NULL, false);
apply_vertex_buffer(vbc, _current_shader_context);
const GeomVertexAnimationSpec &animation =
vertex_data->get_format()->get_animation();
data_reader->get_format()->get_animation();
if (animation.get_animation_type() == Geom::AT_hardware) {
// Set up vertex blending.
switch (animation.get_num_transforms()) {
@@ -1317,7 +1319,7 @@ data = _vertex_data -> get_array (first_index);
set_render_state(D3DRS_INDEXEDVERTEXBLENDENABLE, FALSE);
}
const TransformTable *table = vertex_data->get_transform_table();
const TransformTable *table = data_reader->get_transform_table();
if (table != (TransformTable *)NULL) {
for (int i = 0; i < table->get_num_transforms(); i++) {
LMatrix4f mat;
@@ -1340,14 +1342,14 @@ data = _vertex_data -> get_array (first_index);
_vertex_blending_enabled = false;
}
if (_transform_stale && !_vertex_data->is_vertex_transformed()) {
if (_transform_stale && !_data_reader->is_vertex_transformed()) {
const D3DMATRIX *d3d_mat = (const D3DMATRIX *)_internal_transform->get_mat().get_data();
_d3d_device->SetTransform(D3DTS_WORLD, d3d_mat);
_transform_stale = false;
}
}
if (_vertex_data->is_vertex_transformed()) {
if (_data_reader->is_vertex_transformed()) {
// If the vertex data claims to be already transformed into clip
// coordinates, wipe out the current projection and modelview
// matrix (so we don't attempt to transform it again).
@@ -1376,20 +1378,20 @@ data = _vertex_data -> get_array (first_index);
// Description: Draws a series of disconnected triangles.
////////////////////////////////////////////////////////////////////
void DXGraphicsStateGuardian9::
draw_triangles(const GeomTriangles *primitive) {
draw_triangles(const GeomPrimitivePipelineReader *reader) {
PStatTimer timer(_draw_primitive_pcollector);
// DBG_SH5 dxgsg9_cat.debug ( ) << "draw_triangles 1\n"; DBG_E
_vertices_tri_pcollector.add_level(primitive->get_num_vertices());
_vertices_tri_pcollector.add_level(reader->get_num_vertices());
_primitive_batches_tri_pcollector.add_level(1);
if (primitive->is_indexed()) {
int min_vertex = dx_broken_max_index ? 0 : primitive->get_min_vertex();
int max_vertex = primitive->get_max_vertex();
if (reader->is_indexed()) {
int min_vertex = dx_broken_max_index ? 0 : reader->get_min_vertex();
int max_vertex = reader->get_max_vertex();
if (_active_vbuffer != NULL) {
// Indexed, vbuffers.
IndexBufferContext *ibc = ((GeomPrimitive *)primitive)->prepare_now(get_prepared_objects(), this);
IndexBufferContext *ibc = ((GeomPrimitive *)(reader->get_object()))->prepare_now(get_prepared_objects(), this);
nassertv(ibc != (IndexBufferContext *)NULL);
apply_index_buffer(ibc);
@@ -1398,22 +1400,22 @@ draw_triangles(const GeomTriangles *primitive) {
_d3d_device->DrawIndexedPrimitive
(D3DPT_TRIANGLELIST, 0,
min_vertex, max_vertex - min_vertex + 1,
0, primitive->get_num_primitives());
0, reader->get_num_primitives());
} else {
// Indexed, client arrays.
//DBG_SH2 dxgsg9_cat.debug ( ) << "draw_indexed_primitive_up \n"; DBG_E
D3DFORMAT index_type = get_index_type(primitive->get_index_type());
D3DFORMAT index_type = get_index_type(reader->get_index_type());
draw_indexed_primitive_up
(D3DPT_TRIANGLELIST,
min_vertex, max_vertex,
primitive->get_num_primitives(),
primitive->get_data(),
reader->get_num_primitives(),
reader->get_data(),
index_type,
_vertex_data->get_array(0)->get_data(),
_vertex_data->get_format()->get_array(0)->get_stride());
_data_reader->get_array_reader(0)->get_data(),
_data_reader->get_format()->get_array(0)->get_stride());
}
} else {
if (_active_vbuffer != NULL) {
@@ -1423,19 +1425,19 @@ draw_triangles(const GeomTriangles *primitive) {
_d3d_device->DrawPrimitive
(D3DPT_TRIANGLELIST,
primitive->get_first_vertex(),
primitive->get_num_primitives());
reader->get_first_vertex(),
reader->get_num_primitives());
} else {
// Nonindexed, client arrays.
//DBG_SH2 dxgsg9_cat.debug ( ) << "draw_primitive_up \n"; DBG_E
draw_primitive_up(D3DPT_TRIANGLELIST, primitive->get_num_primitives(),
primitive->get_first_vertex(),
primitive->get_num_vertices(),
_vertex_data->get_array(0)->get_data(),
_vertex_data->get_format()->get_array(0)->get_stride());
draw_primitive_up(D3DPT_TRIANGLELIST, reader->get_num_primitives(),
reader->get_first_vertex(),
reader->get_num_vertices(),
_data_reader->get_array_reader(0)->get_data(),
_data_reader->get_format()->get_array(0)->get_stride());
}
}
@@ -1448,7 +1450,7 @@ draw_triangles(const GeomTriangles *primitive) {
// Description: Draws a series of triangle strips.
////////////////////////////////////////////////////////////////////
void DXGraphicsStateGuardian9::
draw_tristrips(const GeomTristrips *primitive) {
draw_tristrips(const GeomPrimitivePipelineReader *reader) {
PStatTimer timer(_draw_primitive_pcollector);
DBG_SH5 dxgsg9_cat.debug ( ) << "draw_tristrips\n"; DBG_E
@@ -1456,80 +1458,80 @@ draw_tristrips(const GeomTristrips *primitive) {
if (connect_triangle_strips && _current_fill_mode != RenderModeAttrib::M_wireframe) {
// One long triangle strip, connected by the degenerate vertices
// that have already been set up within the primitive.
_vertices_tristrip_pcollector.add_level(primitive->get_num_vertices());
_vertices_tristrip_pcollector.add_level(reader->get_num_vertices());
_primitive_batches_tristrip_pcollector.add_level(1);
if (primitive->is_indexed()) {
int min_vertex = dx_broken_max_index ? 0 : primitive->get_min_vertex();
int max_vertex = primitive->get_max_vertex();
if (reader->is_indexed()) {
int min_vertex = dx_broken_max_index ? 0 : reader->get_min_vertex();
int max_vertex = reader->get_max_vertex();
if (_active_vbuffer != NULL) {
// Indexed, vbuffers, one line triangle strip.
IndexBufferContext *ibc = ((GeomPrimitive *)primitive)->prepare_now(get_prepared_objects(), this);
IndexBufferContext *ibc = ((GeomPrimitive *)(reader->get_object()))->prepare_now(get_prepared_objects(), this);
nassertv(ibc != (IndexBufferContext *)NULL);
apply_index_buffer(ibc);
//dxgsg9_cat.error ( ) << "DrawIndexedPrimitive D3DPT_TRIANGLESTRIP VERTICES: " << primitive->get_num_vertices ( ) << "\n";
//dxgsg9_cat.error ( ) << "DrawIndexedPrimitive D3DPT_TRIANGLESTRIP VERTICES: " << reader->get_num_vertices ( ) << "\n";
_d3d_device->DrawIndexedPrimitive
(D3DPT_TRIANGLESTRIP, 0,
min_vertex, max_vertex - min_vertex + 1,
0, primitive->get_num_vertices() - 2);
0, reader->get_num_vertices() - 2);
} else {
//dxgsg9_cat.error ( ) << "draw_indexed_primitive_up D3DPT_TRIANGLESTRIP VERTICES: " << primitive->get_num_vertices ( ) << "\n";
//dxgsg9_cat.error ( ) << "draw_indexed_primitive_up D3DPT_TRIANGLESTRIP VERTICES: " << reader->get_num_vertices ( ) << "\n";
// Indexed, client arrays, one long triangle strip.
D3DFORMAT index_type = get_index_type(primitive->get_index_type());
D3DFORMAT index_type = get_index_type(reader->get_index_type());
draw_indexed_primitive_up
(D3DPT_TRIANGLESTRIP,
min_vertex, max_vertex,
primitive->get_num_vertices() - 2,
primitive->get_data(), index_type,
_vertex_data->get_array(0)->get_data(),
_vertex_data->get_format()->get_array(0)->get_stride());
reader->get_num_vertices() - 2,
reader->get_data(), index_type,
_data_reader->get_array_reader(0)->get_data(),
_data_reader->get_format()->get_array(0)->get_stride());
}
} else {
if (_active_vbuffer != NULL) {
// Nonindexed, vbuffers, one long triangle strip.
//dxgsg9_cat.error ( ) << "DrawPrimitive D3DPT_TRIANGLESTRIP " << primitive->get_first_vertex ( ) << " VERTICES: " << primitive->get_num_vertices ( ) << "\n";
//dxgsg9_cat.error ( ) << "DrawPrimitive D3DPT_TRIANGLESTRIP " << reader->get_first_vertex ( ) << " VERTICES: " << reader->get_num_vertices ( ) << "\n";
_d3d_device->DrawPrimitive
(D3DPT_TRIANGLESTRIP,
primitive->get_first_vertex(),
primitive->get_num_vertices() - 2);
reader->get_first_vertex(),
reader->get_num_vertices() - 2);
} else {
// Indexed, client arrays, one long triangle strip.
draw_primitive_up(D3DPT_TRIANGLESTRIP,
primitive->get_num_vertices() - 2,
primitive->get_first_vertex(),
primitive->get_num_vertices(),
_vertex_data->get_array(0)->get_data(),
_vertex_data->get_format()->get_array(0)->get_stride());
reader->get_num_vertices() - 2,
reader->get_first_vertex(),
reader->get_num_vertices(),
_data_reader->get_array_reader(0)->get_data(),
_data_reader->get_format()->get_array(0)->get_stride());
}
}
} else {
// Send the individual triangle strips, stepping over the
// degenerate vertices.
CPTA_int ends = primitive->get_ends();
CPTA_int ends = reader->get_ends();
_primitive_batches_tristrip_pcollector.add_level(ends.size());
if (primitive->is_indexed()) {
CPTA_int ends = primitive->get_ends();
int index_stride = primitive->get_index_stride();
if (reader->is_indexed()) {
CPTA_int ends = reader->get_ends();
int index_stride = reader->get_index_stride();
_primitive_batches_tristrip_pcollector.add_level(ends.size());
GeomVertexReader mins(primitive->get_mins(), 0);
GeomVertexReader maxs(primitive->get_maxs(), 0);
nassertv(primitive->get_mins()->get_num_rows() == (int)ends.size() &&
primitive->get_maxs()->get_num_rows() == (int)ends.size());
GeomVertexReader mins(reader->get_mins(), 0);
GeomVertexReader maxs(reader->get_maxs(), 0);
nassertv(reader->get_mins()->get_num_rows() == (int)ends.size() &&
reader->get_maxs()->get_num_rows() == (int)ends.size());
if (_active_vbuffer != NULL) {
// Indexed, vbuffers, individual triangle strips.
IndexBufferContext *ibc = ((GeomPrimitive *)primitive)->prepare_now(get_prepared_objects(), this);
IndexBufferContext *ibc = ((GeomPrimitive *)(reader->get_object()))->prepare_now(get_prepared_objects(), this);
nassertv(ibc != (IndexBufferContext *)NULL);
apply_index_buffer(ibc);
@@ -1549,10 +1551,10 @@ draw_tristrips(const GeomTristrips *primitive) {
} else {
// Indexed, client arrays, individual triangle strips.
CPTA_uchar array_data = _vertex_data->get_array(0)->get_data();
int stride = _vertex_data->get_format()->get_array(0)->get_stride();
CPTA_uchar vertices = primitive->get_data();
D3DFORMAT index_type = get_index_type(primitive->get_index_type());
CPTA_uchar array_data = _data_reader->get_array_reader(0)->get_data();
int stride = _data_reader->get_format()->get_array(0)->get_stride();
CPTA_uchar vertices = reader->get_data();
D3DFORMAT index_type = get_index_type(reader->get_index_type());
unsigned int start = 0;
for (size_t i = 0; i < ends.size(); i++) {
@@ -1570,7 +1572,7 @@ draw_tristrips(const GeomTristrips *primitive) {
}
}
} else {
unsigned int first_vertex = primitive->get_first_vertex();
unsigned int first_vertex = reader->get_first_vertex();
if (_active_vbuffer != NULL) {
// Nonindexed, vbuffers, individual triangle strips.
@@ -1586,8 +1588,8 @@ draw_tristrips(const GeomTristrips *primitive) {
} else {
// Nonindexed, client arrays, individual triangle strips.
CPTA_uchar array_data = _vertex_data->get_array(0)->get_data();
int stride = _vertex_data->get_format()->get_array(0)->get_stride();
CPTA_uchar array_data = _data_reader->get_array_reader(0)->get_data();
int stride = _data_reader->get_format()->get_array(0)->get_stride();
unsigned int start = 0;
for (size_t i = 0; i < ends.size(); i++) {
@@ -1610,30 +1612,30 @@ draw_tristrips(const GeomTristrips *primitive) {
// Description: Draws a series of triangle fans.
////////////////////////////////////////////////////////////////////
void DXGraphicsStateGuardian9::
draw_trifans(const GeomTrifans *primitive) {
draw_trifans(const GeomPrimitivePipelineReader *reader) {
PStatTimer timer(_draw_primitive_pcollector);
DBG_SH5 dxgsg9_cat.debug ( ) << "draw_trifans\n"; DBG_E
CPTA_int ends = primitive->get_ends();
CPTA_int ends = reader->get_ends();
_primitive_batches_trifan_pcollector.add_level(ends.size());
if (primitive->is_indexed()) {
int min_vertex = dx_broken_max_index ? 0 : primitive->get_min_vertex();
int max_vertex = primitive->get_max_vertex();
if (reader->is_indexed()) {
int min_vertex = dx_broken_max_index ? 0 : reader->get_min_vertex();
int max_vertex = reader->get_max_vertex();
// Send the individual triangle fans. There's no connecting fans
// with degenerate vertices, so no worries about that.
int index_stride = primitive->get_index_stride();
int index_stride = reader->get_index_stride();
GeomVertexReader mins(primitive->get_mins(), 0);
GeomVertexReader maxs(primitive->get_maxs(), 0);
nassertv(primitive->get_mins()->get_num_rows() == (int)ends.size() &&
primitive->get_maxs()->get_num_rows() == (int)ends.size());
GeomVertexReader mins(reader->get_mins(), 0);
GeomVertexReader maxs(reader->get_maxs(), 0);
nassertv(reader->get_mins()->get_num_rows() == (int)ends.size() &&
reader->get_maxs()->get_num_rows() == (int)ends.size());
if (_active_vbuffer != NULL) {
// Indexed, vbuffers.
IndexBufferContext *ibc = ((GeomPrimitive *)primitive)->prepare_now(get_prepared_objects(), this);
IndexBufferContext *ibc = ((GeomPrimitive *)(reader->get_object()))->prepare_now(get_prepared_objects(), this);
nassertv(ibc != (IndexBufferContext *)NULL);
apply_index_buffer(ibc);
@@ -1652,10 +1654,10 @@ draw_trifans(const GeomTrifans *primitive) {
} else {
// Indexed, client arrays.
CPTA_uchar array_data = _vertex_data->get_array(0)->get_data();
int stride = _vertex_data->get_format()->get_array(0)->get_stride();
CPTA_uchar vertices = primitive->get_data();
D3DFORMAT index_type = get_index_type(primitive->get_index_type());
CPTA_uchar array_data = _data_reader->get_array_reader(0)->get_data();
int stride = _data_reader->get_format()->get_array(0)->get_stride();
CPTA_uchar vertices = reader->get_data();
D3DFORMAT index_type = get_index_type(reader->get_index_type());
unsigned int start = 0;
for (size_t i = 0; i < ends.size(); i++) {
@@ -1673,7 +1675,7 @@ draw_trifans(const GeomTrifans *primitive) {
}
}
} else {
unsigned int first_vertex = primitive->get_first_vertex();
unsigned int first_vertex = reader->get_first_vertex();
if (_active_vbuffer != NULL) {
// Nonindexed, vbuffers.
@@ -1689,8 +1691,8 @@ draw_trifans(const GeomTrifans *primitive) {
} else {
// Nonindexed, client arrays.
CPTA_uchar array_data = _vertex_data->get_array(0)->get_data();
int stride = _vertex_data->get_format()->get_array(0)->get_stride();
CPTA_uchar array_data = _data_reader->get_array_reader(0)->get_data();
int stride = _data_reader->get_format()->get_array(0)->get_stride();
unsigned int start = 0;
for (size_t i = 0; i < ends.size(); i++) {
@@ -1712,18 +1714,18 @@ draw_trifans(const GeomTrifans *primitive) {
// Description: Draws a series of disconnected line segments.
////////////////////////////////////////////////////////////////////
void DXGraphicsStateGuardian9::
draw_lines(const GeomLines *primitive) {
draw_lines(const GeomPrimitivePipelineReader *reader) {
PStatTimer timer(_draw_primitive_pcollector);
_vertices_other_pcollector.add_level(primitive->get_num_vertices());
_vertices_other_pcollector.add_level(reader->get_num_vertices());
_primitive_batches_other_pcollector.add_level(1);
if (primitive->is_indexed()) {
int min_vertex = dx_broken_max_index ? 0 : primitive->get_min_vertex();
int max_vertex = primitive->get_max_vertex();
if (reader->is_indexed()) {
int min_vertex = dx_broken_max_index ? 0 : reader->get_min_vertex();
int max_vertex = reader->get_max_vertex();
if (_active_vbuffer != NULL) {
// Indexed, vbuffers.
IndexBufferContext *ibc = ((GeomPrimitive *)primitive)->prepare_now(get_prepared_objects(), this);
IndexBufferContext *ibc = ((GeomPrimitive *)(reader->get_object()))->prepare_now(get_prepared_objects(), this);
nassertv(ibc != (IndexBufferContext *)NULL);
apply_index_buffer(ibc);
@@ -1731,36 +1733,36 @@ draw_lines(const GeomLines *primitive) {
(D3DPT_LINELIST,
0,
min_vertex, max_vertex - min_vertex + 1,
0, primitive->get_num_primitives());
0, reader->get_num_primitives());
} else {
// Indexed, client arrays.
D3DFORMAT index_type = get_index_type(primitive->get_index_type());
D3DFORMAT index_type = get_index_type(reader->get_index_type());
draw_indexed_primitive_up
(D3DPT_LINELIST,
min_vertex, max_vertex,
primitive->get_num_primitives(),
primitive->get_data(),
reader->get_num_primitives(),
reader->get_data(),
index_type,
_vertex_data->get_array(0)->get_data(),
_vertex_data->get_format()->get_array(0)->get_stride());
_data_reader->get_array_reader(0)->get_data(),
_data_reader->get_format()->get_array(0)->get_stride());
}
} else {
if (_active_vbuffer != NULL) {
// Nonindexed, vbuffers.
_d3d_device->DrawPrimitive
(D3DPT_LINELIST,
primitive->get_first_vertex(),
primitive->get_num_primitives());
reader->get_first_vertex(),
reader->get_num_primitives());
} else {
// Nonindexed, client arrays.
draw_primitive_up(D3DPT_LINELIST, primitive->get_num_primitives(),
primitive->get_first_vertex(),
primitive->get_num_vertices(),
_vertex_data->get_array(0)->get_data(),
_vertex_data->get_format()->get_array(0)->get_stride());
draw_primitive_up(D3DPT_LINELIST, reader->get_num_primitives(),
reader->get_first_vertex(),
reader->get_num_vertices(),
_data_reader->get_array_reader(0)->get_data(),
_data_reader->get_format()->get_array(0)->get_stride());
}
}
}
@@ -1771,7 +1773,7 @@ draw_lines(const GeomLines *primitive) {
// Description: Draws a series of line strips.
////////////////////////////////////////////////////////////////////
void DXGraphicsStateGuardian9::
draw_linestrips(const GeomLinestrips *primitive) {
draw_linestrips(const GeomPrimitivePipelineReader *reader) {
PStatTimer timer(_draw_primitive_pcollector);
}
@@ -1781,29 +1783,29 @@ draw_linestrips(const GeomLinestrips *primitive) {
// Description: Draws a series of disconnected points.
////////////////////////////////////////////////////////////////////
void DXGraphicsStateGuardian9::
draw_points(const GeomPoints *primitive) {
draw_points(const GeomPrimitivePipelineReader *reader) {
PStatTimer timer(_draw_primitive_pcollector);
_vertices_other_pcollector.add_level(primitive->get_num_vertices());
_vertices_other_pcollector.add_level(reader->get_num_vertices());
_primitive_batches_other_pcollector.add_level(1);
// The munger should have protected us from indexed points--DirectX
// doesn't support them.
nassertv(!primitive->is_indexed());
nassertv(!reader->is_indexed());
if (_active_vbuffer != NULL) {
// Nonindexed, vbuffers.
_d3d_device->DrawPrimitive
(D3DPT_POINTLIST,
primitive->get_first_vertex(),
primitive->get_num_primitives());
reader->get_first_vertex(),
reader->get_num_primitives());
} else {
// Nonindexed, client arrays.
draw_primitive_up(D3DPT_POINTLIST, primitive->get_num_primitives(),
primitive->get_first_vertex(),
primitive->get_num_vertices(),
_vertex_data->get_array(0)->get_data(),
_vertex_data->get_format()->get_array(0)->get_stride());
draw_primitive_up(D3DPT_POINTLIST, reader->get_num_primitives(),
reader->get_first_vertex(),
reader->get_num_vertices(),
_data_reader->get_array_reader(0)->get_data(),
_data_reader->get_format()->get_array(0)->get_stride());
}
}
@@ -1824,7 +1826,7 @@ end_draw_primitives() {
_vertex_blending_enabled = false;
}
if (_vertex_data->is_vertex_transformed()) {
if (_data_reader->is_vertex_transformed()) {
// Restore the projection matrix that we wiped out above.
_d3d_device->SetTransform(D3DTS_PROJECTION,
(D3DMATRIX*)_projection_mat->get_mat().get_data());
+8 -8
View File
@@ -111,15 +111,15 @@ public:
virtual void end_scene();
virtual void end_frame();
virtual bool begin_draw_primitives(const Geom *geom,
virtual bool begin_draw_primitives(const GeomPipelineReader *geom_reader,
const GeomMunger *munger,
const GeomVertexData *vertex_data);
virtual void draw_triangles(const GeomTriangles *primitive);
virtual void draw_tristrips(const GeomTristrips *primitive);
virtual void draw_trifans(const GeomTrifans *primitive);
virtual void draw_lines(const GeomLines *primitive);
virtual void draw_linestrips(const GeomLinestrips *primitive);
virtual void draw_points(const GeomPoints *primitive);
const GeomVertexDataPipelineReader *data_reader);
virtual void draw_triangles(const GeomPrimitivePipelineReader *reader);
virtual void draw_tristrips(const GeomPrimitivePipelineReader *reader);
virtual void draw_trifans(const GeomPrimitivePipelineReader *reader);
virtual void draw_lines(const GeomPrimitivePipelineReader *reader);
virtual void draw_linestrips(const GeomPrimitivePipelineReader *reader);
virtual void draw_points(const GeomPrimitivePipelineReader *reader);
virtual void end_draw_primitives();
virtual void framebuffer_copy_to_texture(Texture *tex, int z, const DisplayRegion *dr,
+2 -2
View File
@@ -714,7 +714,7 @@ update_shader_vertex_arrays(CLP(ShaderContext) *prev, GSG *gsg)
{
if (_vertex_element_array == 0) {
bool error;
const GeomVertexArrayData *array_data;
const GeomVertexArrayDataPipelineReader *array_reader;
Geom::NumericType numeric_type;
int start, stride, num_values;
int nvarying = _var_spec.size();
@@ -744,7 +744,7 @@ update_shader_vertex_arrays(CLP(ShaderContext) *prev, GSG *gsg)
}
}
}
if (gsg->_vertex_data->get_array_info(name, array_data, num_values, numeric_type, start, stride)) {
if (gsg->_data_reader->get_array_info(name, array_reader, num_values, numeric_type, start, stride)) {
if (false) {
+16
View File
@@ -252,6 +252,22 @@ test_ref_count_integrity() const {
#endif
}
////////////////////////////////////////////////////////////////////
// Function: ReferenceCount::test_ref_count_nonzero
// Access: Published
// Description: Does some easy checks to make sure that the reference
// count isn't zero, or completely bogus. Returns true
// if ok, false otherwise.
////////////////////////////////////////////////////////////////////
INLINE bool ReferenceCount::
test_ref_count_nonzero() const {
#ifndef NDEBUG
return do_test_ref_count_nonzero();
#else
return true;
#endif
}
////////////////////////////////////////////////////////////////////
// Function: ReferenceCount::local_object
// Access: Public
+14
View File
@@ -50,6 +50,20 @@ do_test_ref_count_integrity() const {
return true;
}
////////////////////////////////////////////////////////////////////
// Function: ReferenceCount::do_test_ref_count_nonzero
// Access: Protected
// Description: Returns true if the reference count is nonzero, false
// otherwise.
////////////////////////////////////////////////////////////////////
bool ReferenceCount::
do_test_ref_count_nonzero() const {
nassertr(do_test_ref_count_integrity(), false);
nassertr(_ref_count > 0, false);
return true;
}
////////////////////////////////////////////////////////////////////
// Function: ReferenceCount::create_weak_list
// Access: Private
+2
View File
@@ -55,6 +55,7 @@ PUBLISHED:
INLINE bool unref() const;
INLINE bool test_ref_count_integrity() const;
INLINE bool test_ref_count_nonzero() const;
public:
INLINE void local_object();
@@ -66,6 +67,7 @@ public:
protected:
bool do_test_ref_count_integrity() const;
bool do_test_ref_count_nonzero() const;
private:
void create_weak_list();
+155 -148
View File
@@ -1356,23 +1356,24 @@ end_frame() {
// are ok, false to abort this group of primitives.
////////////////////////////////////////////////////////////////////
bool CLP(GraphicsStateGuardian)::
begin_draw_primitives(const Geom *geom, const GeomMunger *munger,
const GeomVertexData *vertex_data) {
begin_draw_primitives(const GeomPipelineReader *geom_reader,
const GeomMunger *munger,
const GeomVertexDataPipelineReader *data_reader) {
#ifndef NDEBUG
if (GLCAT.is_spam()) {
GLCAT.spam() << "begin_draw_primitives: " << *vertex_data << "\n";
GLCAT.spam() << "begin_draw_primitives: " << *(data_reader->get_object()) << "\n";
}
#endif // NDEBUG
if (!GraphicsStateGuardian::begin_draw_primitives(geom, munger, vertex_data)) {
if (!GraphicsStateGuardian::begin_draw_primitives(geom_reader, munger, data_reader)) {
return false;
}
nassertr(_vertex_data != (GeomVertexData *)NULL, false);
nassertr(_data_reader != (GeomVertexDataPipelineReader *)NULL, false);
_geom_display_list = 0;
if (_auto_antialias_mode) {
switch (geom->get_primitive_type()) {
switch (geom_reader->get_primitive_type()) {
case GeomPrimitive::PT_polygons:
setup_antialias_polygon();
break;
@@ -1396,7 +1397,7 @@ begin_draw_primitives(const Geom *geom, const GeomMunger *munger,
}
const GeomVertexAnimationSpec &animation =
_vertex_data->get_format()->get_animation();
_data_reader->get_format()->get_animation();
bool hardware_animation = (animation.get_animation_type() == Geom::AT_hardware);
if (hardware_animation) {
// Set up the transform matrices for vertex blending.
@@ -1404,7 +1405,7 @@ begin_draw_primitives(const Geom *geom, const GeomMunger *munger,
GLP(Enable)(GL_VERTEX_BLEND_ARB);
_glVertexBlendARB(animation.get_num_transforms());
const TransformTable *table = _vertex_data->get_transform_table();
const TransformTable *table = _data_reader->get_transform_table();
if (table != (TransformTable *)NULL) {
if (animation.get_indexed_transforms()) {
nassertr(_supports_matrix_palette, false);
@@ -1481,7 +1482,7 @@ begin_draw_primitives(const Geom *geom, const GeomMunger *munger,
}
}
if (_vertex_data->is_vertex_transformed()) {
if (_data_reader->is_vertex_transformed()) {
// If the vertex data claims to be already transformed into clip
// coordinates, wipe out the current projection and modelview
// matrix (so we don't attempt to transform it again).
@@ -1493,8 +1494,8 @@ begin_draw_primitives(const Geom *geom, const GeomMunger *munger,
GLP(LoadIdentity)();
}
if (geom->get_usage_hint() == Geom::UH_static &&
_vertex_data->get_usage_hint() == Geom::UH_static &&
if (geom_reader->get_usage_hint() == Geom::UH_static &&
_data_reader->get_usage_hint() == Geom::UH_static &&
display_lists && (!hardware_animation || display_list_animation)) {
// If the geom claims to be totally static, try to build it into
// a display list.
@@ -1518,11 +1519,11 @@ begin_draw_primitives(const Geom *geom, const GeomMunger *munger,
_current_ibuffer_index = 0;
}
GeomContext *gc = ((Geom *)geom)->prepare_now(get_prepared_objects(), this);
GeomContext *gc = ((Geom *)geom_reader->get_object())->prepare_now(get_prepared_objects(), this);
nassertr(gc != (GeomContext *)NULL, false);
CLP(GeomContext) *ggc = DCAST(CLP(GeomContext), gc);
const CLP(GeomMunger) *gmunger = DCAST(CLP(GeomMunger), _munger);
UpdateSeq modified = max(geom->get_modified(), _vertex_data->get_modified());
UpdateSeq modified = max(geom_reader->get_modified(), _data_reader->get_modified());
if (ggc->get_display_list(_geom_display_list, gmunger, modified)) {
// If it hasn't been modified, just play the display list again.
if (GLCAT.is_spam()) {
@@ -1563,8 +1564,8 @@ begin_draw_primitives(const Geom *geom, const GeomMunger *munger,
// Count up the number of vertices used by primitives in the Geom,
// for PStats reporting.
ggc->_num_verts = 0;
for (int i = 0; i < geom->get_num_primitives(); i++) {
ggc->_num_verts += geom->get_primitive(i)->get_num_vertices();
for (int i = 0; i < geom_reader->get_num_primitives(); i++) {
ggc->_num_verts += geom_reader->get_primitive(i)->get_num_vertices();
}
#endif
}
@@ -1610,19 +1611,18 @@ begin_draw_primitives(const Geom *geom, const GeomMunger *munger,
// for setting up their own vertex arrays.
////////////////////////////////////////////////////////////////////
void CLP(GraphicsStateGuardian)::
update_standard_vertex_arrays()
{
update_standard_vertex_arrays() {
const GeomVertexAnimationSpec &animation =
_vertex_data->get_format()->get_animation();
_data_reader->get_format()->get_animation();
bool hardware_animation = (animation.get_animation_type() == Geom::AT_hardware);
#ifdef SUPPORT_IMMEDIATE_MODE
if (_use_sender) {
// We must use immediate mode to render primitives.
_sender.clear();
_sender.add_column(_vertex_data, InternalName::get_normal(),
_sender.add_column(_data_reader, InternalName::get_normal(),
NULL, NULL, GLP(Normal3f), NULL);
if (!_sender.add_column(_vertex_data, InternalName::get_color(),
if (!_sender.add_column(_data_reader, InternalName::get_color(),
NULL, NULL, GLP(Color3f), GLP(Color4f))) {
// If we didn't have a color column, the item color is white.
GLP(Color4f)(1.0f, 1.0f, 1.0f, 1.0f);
@@ -1647,13 +1647,13 @@ update_standard_vertex_arrays()
if (stage_index == 0) {
// Use the original functions for stage 0, in case we don't
// support multitexture.
_sender.add_column(_vertex_data, name,
_sender.add_column(_data_reader, name,
GLP(TexCoord1f), GLP(TexCoord2f),
GLP(TexCoord3f), GLP(TexCoord4f));
} else {
// Other stages require the multitexture functions.
_sender.add_texcoord_column(_vertex_data, name, stage_index,
_sender.add_texcoord_column(_data_reader, name, stage_index,
_glMultiTexCoord1f, _glMultiTexCoord2f,
_glMultiTexCoord3f, _glMultiTexCoord4f);
}
@@ -1673,12 +1673,12 @@ update_standard_vertex_arrays()
if (_supports_vertex_blend) {
if (hardware_animation) {
// Issue the weights and/or transform indices for vertex blending.
_sender.add_vector_column(_vertex_data, InternalName::get_transform_weight(),
_sender.add_vector_column(_data_reader, InternalName::get_transform_weight(),
_glWeightfvARB);
if (animation.get_indexed_transforms()) {
// Issue the matrix palette indices.
_sender.add_vector_uint_column(_vertex_data, InternalName::get_transform_index(),
_sender.add_vector_uint_column(_data_reader, InternalName::get_transform_index(),
_glMatrixIndexuivARB);
}
}
@@ -1686,22 +1686,22 @@ update_standard_vertex_arrays()
// We must add vertex last, because glVertex3f() is the key
// function call that actually issues the vertex.
_sender.add_column(_vertex_data, InternalName::get_vertex(),
_sender.add_column(_data_reader, InternalName::get_vertex(),
NULL, GLP(Vertex2f), GLP(Vertex3f), GLP(Vertex4f));
} else
#endif // SUPPORT_IMMEDIATE_MODE
{
// We may use vertex arrays or buffers to render primitives.
const GeomVertexArrayData *array_data;
const GeomVertexArrayDataPipelineReader *array_reader;
int num_values;
Geom::NumericType numeric_type;
int start;
int stride;
if (_vertex_data->get_normal_info(array_data, numeric_type,
if (_data_reader->get_normal_info(array_reader, numeric_type,
start, stride)) {
const unsigned char *client_pointer = setup_array_data(array_data);
const unsigned char *client_pointer = setup_array_data(array_reader);
GLP(NormalPointer)(get_numeric_type(numeric_type), stride,
client_pointer + start);
GLP(EnableClientState)(GL_NORMAL_ARRAY);
@@ -1709,10 +1709,10 @@ update_standard_vertex_arrays()
GLP(DisableClientState)(GL_NORMAL_ARRAY);
}
if (_vertex_data->get_color_info(array_data, num_values, numeric_type,
if (_data_reader->get_color_info(array_reader, num_values, numeric_type,
start, stride) &&
numeric_type != Geom::NT_packed_dabc) {
const unsigned char *client_pointer = setup_array_data(array_data);
const unsigned char *client_pointer = setup_array_data(array_reader);
GLP(ColorPointer)(num_values, get_numeric_type(numeric_type),
stride, client_pointer + start);
GLP(EnableClientState)(GL_COLOR_ARRAY);
@@ -1742,10 +1742,10 @@ update_standard_vertex_arrays()
// texcoords issued for it.
const InternalName *name = stage->get_texcoord_name();
if (_vertex_data->get_array_info(name, array_data, num_values,
if (_data_reader->get_array_info(name, array_reader, num_values,
numeric_type, start, stride)) {
// The vertex data does have texcoords for this stage.
const unsigned char *client_pointer = setup_array_data(array_data);
const unsigned char *client_pointer = setup_array_data(array_reader);
GLP(TexCoordPointer)(num_values, get_numeric_type(numeric_type),
stride, client_pointer + start);
GLP(EnableClientState)(GL_TEXTURE_COORD_ARRAY);
@@ -1774,10 +1774,10 @@ update_standard_vertex_arrays()
if (_supports_vertex_blend) {
if (hardware_animation) {
// Issue the weights and/or transform indices for vertex blending.
if (_vertex_data->get_array_info(InternalName::get_transform_weight(),
array_data, num_values, numeric_type,
if (_data_reader->get_array_info(InternalName::get_transform_weight(),
array_reader, num_values, numeric_type,
start, stride)) {
const unsigned char *client_pointer = setup_array_data(array_data);
const unsigned char *client_pointer = setup_array_data(array_reader);
_glWeightPointerARB(num_values, get_numeric_type(numeric_type),
stride, client_pointer + start);
GLP(EnableClientState)(GL_WEIGHT_ARRAY_ARB);
@@ -1787,10 +1787,10 @@ update_standard_vertex_arrays()
if (animation.get_indexed_transforms()) {
// Issue the matrix palette indices.
if (_vertex_data->get_array_info(InternalName::get_transform_index(),
array_data, num_values, numeric_type,
if (_data_reader->get_array_info(InternalName::get_transform_index(),
array_reader, num_values, numeric_type,
start, stride)) {
const unsigned char *client_pointer = setup_array_data(array_data);
const unsigned char *client_pointer = setup_array_data(array_reader);
_glMatrixIndexPointerARB(num_values, get_numeric_type(numeric_type),
stride, client_pointer + start);
GLP(EnableClientState)(GL_MATRIX_INDEX_ARRAY_ARB);
@@ -1809,9 +1809,9 @@ update_standard_vertex_arrays()
// There's no requirement that we add vertices last, but we do
// anyway.
if (_vertex_data->get_vertex_info(array_data, num_values, numeric_type,
if (_data_reader->get_vertex_info(array_reader, num_values, numeric_type,
start, stride)) {
const unsigned char *client_pointer = setup_array_data(array_data);
const unsigned char *client_pointer = setup_array_data(array_reader);
GLP(VertexPointer)(num_values, get_numeric_type(numeric_type),
stride, client_pointer + start);
GLP(EnableClientState)(GL_VERTEX_ARRAY);
@@ -1865,38 +1865,39 @@ disable_standard_vertex_arrays()
// Description: Draws a series of disconnected triangles.
////////////////////////////////////////////////////////////////////
void CLP(GraphicsStateGuardian)::
draw_triangles(const GeomTriangles *primitive) {
draw_triangles(const GeomPrimitivePipelineReader *reader) {
PStatTimer timer(_draw_primitive_pcollector);
#ifndef NDEBUG
if (GLCAT.is_spam()) {
GLCAT.spam() << "draw_triangles: " << *primitive << "\n";
GLCAT.spam() << "draw_triangles: " << *(reader->get_object()) << "\n";
}
#endif // NDEBUG
#ifdef SUPPORT_IMMEDIATE_MODE
if (_use_sender) {
draw_immediate_simple_primitives(primitive, GL_TRIANGLES);
draw_immediate_simple_primitives(reader, GL_TRIANGLES);
} else
#endif // SUPPORT_IMMEDIATE_MODE
{
_vertices_tri_pcollector.add_level(primitive->get_num_vertices());
int num_vertices = reader->get_num_vertices();
_vertices_tri_pcollector.add_level(num_vertices);
_primitive_batches_tri_pcollector.add_level(1);
if (primitive->is_indexed()) {
const unsigned char *client_pointer = setup_primitive(primitive);
if (reader->is_indexed()) {
const unsigned char *client_pointer = setup_primitive(reader);
_glDrawRangeElements(GL_TRIANGLES,
primitive->get_min_vertex(),
primitive->get_max_vertex(),
primitive->get_num_vertices(),
get_numeric_type(primitive->get_index_type()),
reader->get_min_vertex(),
reader->get_max_vertex(),
num_vertices,
get_numeric_type(reader->get_index_type()),
client_pointer);
} else {
GLP(DrawArrays)(GL_TRIANGLES,
primitive->get_first_vertex(),
primitive->get_num_vertices());
reader->get_first_vertex(),
num_vertices);
}
}
@@ -1909,20 +1910,20 @@ draw_triangles(const GeomTriangles *primitive) {
// Description: Draws a series of triangle strips.
////////////////////////////////////////////////////////////////////
void CLP(GraphicsStateGuardian)::
draw_tristrips(const GeomTristrips *primitive) {
draw_tristrips(const GeomPrimitivePipelineReader *reader) {
PStatTimer timer(_draw_primitive_pcollector);
report_my_gl_errors();
#ifndef NDEBUG
if (GLCAT.is_spam()) {
GLCAT.spam() << "draw_tristrips: " << *primitive << "\n";
GLCAT.spam() << "draw_tristrips: " << *(reader->get_object()) << "\n";
}
#endif // NDEBUG
#ifdef SUPPORT_IMMEDIATE_MODE
if (_use_sender) {
draw_immediate_composite_primitives(primitive, GL_TRIANGLE_STRIP);
draw_immediate_composite_primitives(reader, GL_TRIANGLE_STRIP);
} else
#endif // SUPPORT_IMMEDIATE_MODE
@@ -1930,35 +1931,36 @@ draw_tristrips(const GeomTristrips *primitive) {
if (connect_triangle_strips && _render_mode != RenderModeAttrib::M_wireframe) {
// One long triangle strip, connected by the degenerate vertices
// that have already been set up within the primitive.
_vertices_tristrip_pcollector.add_level(primitive->get_num_vertices());
int num_vertices = reader->get_num_vertices();
_vertices_tristrip_pcollector.add_level(num_vertices);
_primitive_batches_tristrip_pcollector.add_level(1);
if (primitive->is_indexed()) {
const unsigned char *client_pointer = setup_primitive(primitive);
if (reader->is_indexed()) {
const unsigned char *client_pointer = setup_primitive(reader);
_glDrawRangeElements(GL_TRIANGLE_STRIP,
primitive->get_min_vertex(),
primitive->get_max_vertex(),
primitive->get_num_vertices(),
get_numeric_type(primitive->get_index_type()),
reader->get_min_vertex(),
reader->get_max_vertex(),
num_vertices,
get_numeric_type(reader->get_index_type()),
client_pointer);
} else {
GLP(DrawArrays)(GL_TRIANGLE_STRIP,
primitive->get_first_vertex(),
primitive->get_num_vertices());
reader->get_first_vertex(),
num_vertices);
}
} else {
// Send the individual triangle strips, stepping over the
// degenerate vertices.
CPTA_int ends = primitive->get_ends();
CPTA_int ends = reader->get_ends();
_primitive_batches_tristrip_pcollector.add_level(ends.size());
if (primitive->is_indexed()) {
const unsigned char *client_pointer = setup_primitive(primitive);
int index_stride = primitive->get_index_stride();
GeomVertexReader mins(primitive->get_mins(), 0);
GeomVertexReader maxs(primitive->get_maxs(), 0);
nassertv(primitive->get_mins()->get_num_rows() == (int)ends.size() &&
primitive->get_maxs()->get_num_rows() == (int)ends.size());
if (reader->is_indexed()) {
const unsigned char *client_pointer = setup_primitive(reader);
int index_stride = reader->get_index_stride();
GeomVertexReader mins(reader->get_mins(), 0);
GeomVertexReader maxs(reader->get_maxs(), 0);
nassertv(reader->get_mins()->get_num_rows() == (int)ends.size() &&
reader->get_maxs()->get_num_rows() == (int)ends.size());
unsigned int start = 0;
for (size_t i = 0; i < ends.size(); i++) {
@@ -1966,13 +1968,13 @@ draw_tristrips(const GeomTristrips *primitive) {
_glDrawRangeElements(GL_TRIANGLE_STRIP,
mins.get_data1i(), maxs.get_data1i(),
ends[i] - start,
get_numeric_type(primitive->get_index_type()),
get_numeric_type(reader->get_index_type()),
client_pointer + start * index_stride);
start = ends[i] + 2;
}
} else {
unsigned int start = 0;
int first_vertex = primitive->get_first_vertex();
int first_vertex = reader->get_first_vertex();
for (size_t i = 0; i < ends.size(); i++) {
_vertices_tristrip_pcollector.add_level(ends[i] - start);
GLP(DrawArrays)(GL_TRIANGLE_STRIP, first_vertex + start,
@@ -1992,45 +1994,45 @@ draw_tristrips(const GeomTristrips *primitive) {
// Description: Draws a series of triangle fans.
////////////////////////////////////////////////////////////////////
void CLP(GraphicsStateGuardian)::
draw_trifans(const GeomTrifans *primitive) {
draw_trifans(const GeomPrimitivePipelineReader *reader) {
PStatTimer timer(_draw_primitive_pcollector);
#ifndef NDEBUG
if (GLCAT.is_spam()) {
GLCAT.spam() << "draw_trifans: " << *primitive << "\n";
GLCAT.spam() << "draw_trifans: " << *(reader->get_object()) << "\n";
}
#endif // NDEBUG
#ifdef SUPPORT_IMMEDIATE_MODE
if (_use_sender) {
draw_immediate_composite_primitives(primitive, GL_TRIANGLE_FAN);
draw_immediate_composite_primitives(reader, GL_TRIANGLE_FAN);
} else
#endif // SUPPORT_IMMEDIATE_MODE
{
// Send the individual triangle fans. There's no connecting fans
// with degenerate vertices, so no worries about that.
CPTA_int ends = primitive->get_ends();
CPTA_int ends = reader->get_ends();
_primitive_batches_trifan_pcollector.add_level(ends.size());
if (primitive->is_indexed()) {
const unsigned char *client_pointer = setup_primitive(primitive);
int index_stride = primitive->get_index_stride();
GeomVertexReader mins(primitive->get_mins(), 0);
GeomVertexReader maxs(primitive->get_maxs(), 0);
nassertv(primitive->get_mins()->get_num_rows() == (int)ends.size() &&
primitive->get_maxs()->get_num_rows() == (int)ends.size());
if (reader->is_indexed()) {
const unsigned char *client_pointer = setup_primitive(reader);
int index_stride = reader->get_index_stride();
GeomVertexReader mins(reader->get_mins(), 0);
GeomVertexReader maxs(reader->get_maxs(), 0);
nassertv(reader->get_mins()->get_num_rows() == (int)ends.size() &&
reader->get_maxs()->get_num_rows() == (int)ends.size());
unsigned int start = 0;
for (size_t i = 0; i < ends.size(); i++) {
_vertices_trifan_pcollector.add_level(ends[i] - start);
_glDrawRangeElements(GL_TRIANGLE_FAN,
mins.get_data1i(), maxs.get_data1i(), ends[i] - start,
get_numeric_type(primitive->get_index_type()),
get_numeric_type(reader->get_index_type()),
client_pointer + start * index_stride);
start = ends[i];
}
} else {
unsigned int start = 0;
int first_vertex = primitive->get_first_vertex();
int first_vertex = reader->get_first_vertex();
for (size_t i = 0; i < ends.size(); i++) {
_vertices_trifan_pcollector.add_level(ends[i] - start);
GLP(DrawArrays)(GL_TRIANGLE_FAN, first_vertex + start,
@@ -2049,35 +2051,36 @@ draw_trifans(const GeomTrifans *primitive) {
// Description: Draws a series of disconnected line segments.
////////////////////////////////////////////////////////////////////
void CLP(GraphicsStateGuardian)::
draw_lines(const GeomLines *primitive) {
draw_lines(const GeomPrimitivePipelineReader *reader) {
PStatTimer timer(_draw_primitive_pcollector);
#ifndef NDEBUG
if (GLCAT.is_spam()) {
GLCAT.spam() << "draw_lines: " << *primitive << "\n";
GLCAT.spam() << "draw_lines: " << *(reader->get_object()) << "\n";
}
#endif // NDEBUG
#ifdef SUPPORT_IMMEDIATE_MODE
if (_use_sender) {
draw_immediate_simple_primitives(primitive, GL_LINES);
draw_immediate_simple_primitives(reader, GL_LINES);
} else
#endif // SUPPORT_IMMEDIATE_MODE
{
_vertices_other_pcollector.add_level(primitive->get_num_vertices());
int num_vertices = reader->get_num_vertices();
_vertices_other_pcollector.add_level(num_vertices);
_primitive_batches_other_pcollector.add_level(1);
if (primitive->is_indexed()) {
const unsigned char *client_pointer = setup_primitive(primitive);
if (reader->is_indexed()) {
const unsigned char *client_pointer = setup_primitive(reader);
_glDrawRangeElements(GL_LINES,
primitive->get_min_vertex(),
primitive->get_max_vertex(),
primitive->get_num_vertices(),
get_numeric_type(primitive->get_index_type()),
reader->get_min_vertex(),
reader->get_max_vertex(),
num_vertices,
get_numeric_type(reader->get_index_type()),
client_pointer);
} else {
GLP(DrawArrays)(GL_LINES,
primitive->get_first_vertex(),
primitive->get_num_vertices());
reader->get_first_vertex(),
num_vertices);
}
}
@@ -2090,11 +2093,11 @@ draw_lines(const GeomLines *primitive) {
// Description: Draws a series of line strips.
////////////////////////////////////////////////////////////////////
void CLP(GraphicsStateGuardian)::
draw_linestrips(const GeomLinestrips *primitive) {
draw_linestrips(const GeomPrimitivePipelineReader *reader) {
PStatTimer timer(_draw_primitive_pcollector);
#ifndef NDEBUG
if (GLCAT.is_spam()) {
GLCAT.spam() << "draw_linestrips: " << *primitive << "\n";
GLCAT.spam() << "draw_linestrips: " << *(reader->get_object()) << "\n";
}
#endif // NDEBUG
@@ -2106,35 +2109,36 @@ draw_linestrips(const GeomLinestrips *primitive) {
// Description: Draws a series of disconnected points.
////////////////////////////////////////////////////////////////////
void CLP(GraphicsStateGuardian)::
draw_points(const GeomPoints *primitive) {
draw_points(const GeomPrimitivePipelineReader *reader) {
PStatTimer timer(_draw_primitive_pcollector);
#ifndef NDEBUG
if (GLCAT.is_spam()) {
GLCAT.spam() << "draw_points: " << *primitive << "\n";
GLCAT.spam() << "draw_points: " << *(reader->get_object()) << "\n";
}
#endif // NDEBUG
#ifdef SUPPORT_IMMEDIATE_MODE
if (_use_sender) {
draw_immediate_simple_primitives(primitive, GL_POINTS);
draw_immediate_simple_primitives(reader, GL_POINTS);
} else
#endif // SUPPORT_IMMEDIATE_MODE
{
_vertices_other_pcollector.add_level(primitive->get_num_vertices());
int num_vertices = reader->get_num_vertices();
_vertices_other_pcollector.add_level(num_vertices);
_primitive_batches_other_pcollector.add_level(1);
if (primitive->is_indexed()) {
const unsigned char *client_pointer = setup_primitive(primitive);
if (reader->is_indexed()) {
const unsigned char *client_pointer = setup_primitive(reader);
_glDrawRangeElements(GL_POINTS,
primitive->get_min_vertex(),
primitive->get_max_vertex(),
primitive->get_num_vertices(),
get_numeric_type(primitive->get_index_type()),
reader->get_min_vertex(),
reader->get_max_vertex(),
num_vertices,
get_numeric_type(reader->get_index_type()),
client_pointer);
} else {
GLP(DrawArrays)(GL_POINTS,
primitive->get_first_vertex(),
primitive->get_num_vertices());
reader->get_first_vertex(),
num_vertices);
}
}
@@ -2176,7 +2180,7 @@ end_draw_primitives() {
GLP(LoadMatrixf)(_internal_transform->get_mat().get_data());
}
if (_vertex_data->is_vertex_transformed()) {
if (_data_reader->is_vertex_transformed()) {
// Restore the matrices that we pushed above.
GLP(MatrixMode)(GL_PROJECTION);
GLP(PopMatrix)();
@@ -2704,19 +2708,19 @@ release_vertex_buffer(VertexBufferContext *vbc) {
// memory.
//
// If the buffer object is bound, this function returns
// NULL (reprsenting the start of the buffer object in
// NULL (representing the start of the buffer object in
// server memory); if the buffer object is not bound,
// this function returns the pointer to the data array
// in client memory, that is, the data array passed in.
////////////////////////////////////////////////////////////////////
const unsigned char *CLP(GraphicsStateGuardian)::
setup_array_data(const GeomVertexArrayData *data) {
setup_array_data(const GeomVertexArrayDataPipelineReader *array_reader) {
if (!_supports_buffers) {
// No support for buffer objects; always render from client.
return data->get_data();
return array_reader->get_data();
}
if (!vertex_buffers || _geom_display_list != 0 ||
data->get_usage_hint() == Geom::UH_client) {
array_reader->get_usage_hint() == Geom::UH_client) {
// The array specifies client rendering only, or buffer objects
// are configured off.
if (_current_vbuffer_index != 0) {
@@ -2727,12 +2731,12 @@ setup_array_data(const GeomVertexArrayData *data) {
_glBindBuffer(GL_ARRAY_BUFFER, 0);
_current_vbuffer_index = 0;
}
return data->get_data();
return array_reader->get_data();
}
// Prepare the buffer object and bind it.
VertexBufferContext *vbc = ((GeomVertexArrayData *)data)->prepare_now(get_prepared_objects(), this);
nassertr(vbc != (VertexBufferContext *)NULL, data->get_data());
VertexBufferContext *vbc = ((GeomVertexArrayData *)array_reader->get_object())->prepare_now(get_prepared_objects(), this);
nassertr(vbc != (VertexBufferContext *)NULL, array_reader->get_data());
apply_vertex_buffer(vbc);
// NULL is the OpenGL convention for the first byte of the buffer object.
@@ -2780,9 +2784,10 @@ prepare_index_buffer(GeomPrimitive *data) {
// rendering.
////////////////////////////////////////////////////////////////////
void CLP(GraphicsStateGuardian)::
apply_index_buffer(IndexBufferContext *ibc) {
apply_index_buffer(IndexBufferContext *ibc,
const GeomPrimitivePipelineReader *reader) {
nassertv(_supports_buffers);
nassertv(ibc->get_data()->get_modified() != UpdateSeq::initial());
nassertv(reader->get_modified() != UpdateSeq::initial());
CLP(IndexBufferContext) *gibc = DCAST(CLP(IndexBufferContext), ibc);
@@ -2798,7 +2803,7 @@ apply_index_buffer(IndexBufferContext *ibc) {
if (gibc->was_modified()) {
PStatTimer timer(_load_index_buffer_pcollector);
int num_bytes = gibc->get_data()->get_data_size_bytes();
int num_bytes = reader->get_data_size_bytes();
if (GLCAT.is_spam()) {
GLCAT.spam()
<< "copying " << num_bytes
@@ -2807,12 +2812,12 @@ apply_index_buffer(IndexBufferContext *ibc) {
if (num_bytes != 0) {
if (gibc->changed_size() || gibc->changed_usage_hint()) {
_glBufferData(GL_ELEMENT_ARRAY_BUFFER, num_bytes,
gibc->get_data()->get_data(),
get_usage(gibc->get_data()->get_usage_hint()));
reader->get_data(),
get_usage(reader->get_usage_hint()));
} else {
_glBufferSubData(GL_ELEMENT_ARRAY_BUFFER, 0, num_bytes,
gibc->get_data()->get_data());
reader->get_data());
}
_data_transferred_pcollector.add_level(num_bytes);
}
@@ -2877,13 +2882,13 @@ release_index_buffer(IndexBufferContext *ibc) {
// in client memory, that is, the data array passed in.
////////////////////////////////////////////////////////////////////
const unsigned char *CLP(GraphicsStateGuardian)::
setup_primitive(const GeomPrimitive *data) {
setup_primitive(const GeomPrimitivePipelineReader *reader) {
if (!_supports_buffers) {
// No support for buffer objects; always render from client.
return data->get_data();
return reader->get_data();
}
if (!vertex_buffers || _geom_display_list != 0 ||
data->get_usage_hint() == Geom::UH_client) {
reader->get_usage_hint() == Geom::UH_client) {
// The array specifies client rendering only, or buffer objects
// are configured off.
if (_current_ibuffer_index != 0) {
@@ -2894,13 +2899,13 @@ setup_primitive(const GeomPrimitive *data) {
_glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
_current_ibuffer_index = 0;
}
return data->get_data();
return reader->get_data();
}
// Prepare the buffer object and bind it.
IndexBufferContext *ibc = ((GeomPrimitive *)data)->prepare_now(get_prepared_objects(), this);
nassertr(ibc != (IndexBufferContext *)NULL, data->get_data());
apply_index_buffer(ibc);
IndexBufferContext *ibc = ((GeomPrimitive *)reader->get_object())->prepare_now(get_prepared_objects(), this);
nassertr(ibc != (IndexBufferContext *)NULL, reader->get_data());
apply_index_buffer(ibc, reader);
// NULL is the OpenGL convention for the first byte of the buffer object.
return NULL;
@@ -3926,19 +3931,20 @@ bind_light(Spotlight *light_obj, const NodePath &light, int light_id) {
// primitives of the indicated type.
////////////////////////////////////////////////////////////////////
void CLP(GraphicsStateGuardian)::
draw_immediate_simple_primitives(const GeomPrimitive *primitive, GLenum mode) {
_vertices_immediate_pcollector.add_level(primitive->get_num_vertices());
draw_immediate_simple_primitives(const GeomPrimitivePipelineReader *reader, GLenum mode) {
int num_vertices = reader->get_num_vertices();
_vertices_immediate_pcollector.add_level(num_vertices);
GLP(Begin)(mode);
if (primitive->is_indexed()) {
for (int v = 0; v < primitive->get_num_vertices(); ++v) {
_sender.set_vertex(primitive->get_vertex(v));
if (reader->is_indexed()) {
for (int v = 0; v < num_vertices; ++v) {
_sender.set_vertex(reader->get_vertex(v));
_sender.issue_vertex();
}
} else {
_sender.set_vertex(primitive->get_first_vertex());
for (int v = 0; v < primitive->get_num_vertices(); ++v) {
_sender.set_vertex(reader->get_first_vertex());
for (int v = 0; v < num_vertices; ++v) {
_sender.issue_vertex();
}
}
@@ -3957,12 +3963,13 @@ draw_immediate_simple_primitives(const GeomPrimitive *primitive, GLenum mode) {
// several begin/end groups.
////////////////////////////////////////////////////////////////////
void CLP(GraphicsStateGuardian)::
draw_immediate_composite_primitives(const GeomPrimitive *primitive, GLenum mode) {
_vertices_immediate_pcollector.add_level(primitive->get_num_vertices());
CPTA_int ends = primitive->get_ends();
int num_unused_vertices_per_primitive = primitive->get_num_unused_vertices_per_primitive();
draw_immediate_composite_primitives(const GeomPrimitivePipelineReader *reader, GLenum mode) {
int num_vertices = reader->get_num_vertices();
_vertices_immediate_pcollector.add_level(num_vertices);
CPTA_int ends = reader->get_ends();
int num_unused_vertices_per_primitive = reader->get_object()->get_num_unused_vertices_per_primitive();
if (primitive->is_indexed()) {
if (reader->is_indexed()) {
int begin = 0;
CPTA_int::const_iterator ei;
for (ei = ends.begin(); ei != ends.end(); ++ei) {
@@ -3970,7 +3977,7 @@ draw_immediate_composite_primitives(const GeomPrimitive *primitive, GLenum mode)
GLP(Begin)(mode);
for (int v = begin; v < end; ++v) {
_sender.set_vertex(primitive->get_vertex(v));
_sender.set_vertex(reader->get_vertex(v));
_sender.issue_vertex();
}
GLP(End)();
@@ -3979,7 +3986,7 @@ draw_immediate_composite_primitives(const GeomPrimitive *primitive, GLenum mode)
}
} else {
_sender.set_vertex(primitive->get_first_vertex());
_sender.set_vertex(reader->get_first_vertex());
int begin = 0;
CPTA_int::const_iterator ei;
for (ei = ends.begin(); ei != ends.end(); ++ei) {
+14 -13
View File
@@ -96,15 +96,15 @@ public:
virtual bool begin_frame();
virtual void end_frame();
virtual bool begin_draw_primitives(const Geom *geom,
virtual bool begin_draw_primitives(const GeomPipelineReader *geom_reader,
const GeomMunger *munger,
const GeomVertexData *vertex_data);
virtual void draw_triangles(const GeomTriangles *primitive);
virtual void draw_tristrips(const GeomTristrips *primitive);
virtual void draw_trifans(const GeomTrifans *primitive);
virtual void draw_lines(const GeomLines *primitive);
virtual void draw_linestrips(const GeomLinestrips *primitive);
virtual void draw_points(const GeomPoints *primitive);
const GeomVertexDataPipelineReader *data_reader);
virtual void draw_triangles(const GeomPrimitivePipelineReader *reader);
virtual void draw_tristrips(const GeomPrimitivePipelineReader *reader);
virtual void draw_trifans(const GeomPrimitivePipelineReader *reader);
virtual void draw_lines(const GeomPrimitivePipelineReader *reader);
virtual void draw_linestrips(const GeomPrimitivePipelineReader *reader);
virtual void draw_points(const GeomPrimitivePipelineReader *reader);
virtual void end_draw_primitives();
INLINE bool draw_display_list(GeomContext *gc);
@@ -124,12 +124,13 @@ public:
virtual VertexBufferContext *prepare_vertex_buffer(GeomVertexArrayData *data);
void apply_vertex_buffer(VertexBufferContext *vbc);
virtual void release_vertex_buffer(VertexBufferContext *vbc);
const unsigned char *setup_array_data(const GeomVertexArrayData *data);
const unsigned char *setup_array_data(const GeomVertexArrayDataPipelineReader *data);
virtual IndexBufferContext *prepare_index_buffer(GeomPrimitive *data);
void apply_index_buffer(IndexBufferContext *ibc);
void apply_index_buffer(IndexBufferContext *ibc,
const GeomPrimitivePipelineReader *reader);
virtual void release_index_buffer(IndexBufferContext *ibc);
const unsigned char *setup_primitive(const GeomPrimitive *data);
const unsigned char *setup_primitive(const GeomPrimitivePipelineReader *reader);
virtual void begin_occlusion_query();
virtual PT(OcclusionQueryContext) end_occlusion_query();
@@ -159,8 +160,8 @@ public:
const float *get_light_color(Light *light) const;
#ifdef SUPPORT_IMMEDIATE_MODE
void draw_immediate_simple_primitives(const GeomPrimitive *primitive, GLenum mode);
void draw_immediate_composite_primitives(const GeomPrimitive *primitive, GLenum mode);
void draw_immediate_simple_primitives(const GeomPrimitivePipelineReader *reader, GLenum mode);
void draw_immediate_composite_primitives(const GeomPrimitivePipelineReader *reader, GLenum mode);
#endif // SUPPORT_IMMEDIATE_MODE
INLINE static bool report_errors(int line, const char *source_file);
+12 -12
View File
@@ -89,10 +89,10 @@ issue_vertex() {
// named column doesn't exist in the vertex data).
////////////////////////////////////////////////////////////////////
bool CLP(ImmediateModeSender)::
add_column(const GeomVertexData *vertex_data, const InternalName *name,
add_column(const GeomVertexDataPipelineReader *data_reader, const InternalName *name,
Func1f *func1f, Func2f *func2f, Func3f *func3f, Func4f *func4f) {
if (vertex_data->has_column(name)) {
GeomVertexReader *reader = new GeomVertexReader(vertex_data, name);
if (data_reader->has_column(name)) {
GeomVertexReader *reader = new GeomVertexReader(data_reader, name);
ComponentSender *sender = NULL;
const GeomVertexColumn *column = reader->get_column();
switch (column->get_num_components()) {
@@ -151,12 +151,12 @@ add_column(const GeomVertexData *vertex_data, const InternalName *name,
// named column doesn't exist in the vertex data).
////////////////////////////////////////////////////////////////////
bool CLP(ImmediateModeSender)::
add_texcoord_column(const GeomVertexData *vertex_data,
add_texcoord_column(const GeomVertexDataPipelineReader *data_reader,
const InternalName *name, int stage_index,
TexcoordFunc1f *func1f, TexcoordFunc2f *func2f,
TexcoordFunc3f *func3f, TexcoordFunc4f *func4f) {
if (vertex_data->has_column(name)) {
GeomVertexReader *reader = new GeomVertexReader(vertex_data, name);
if (data_reader->has_column(name)) {
GeomVertexReader *reader = new GeomVertexReader(data_reader, name);
ComponentSender *sender = NULL;
const GeomVertexColumn *column = reader->get_column();
switch (column->get_num_components()) {
@@ -209,10 +209,10 @@ add_texcoord_column(const GeomVertexData *vertex_data,
// named column doesn't exist in the vertex data).
////////////////////////////////////////////////////////////////////
bool CLP(ImmediateModeSender)::
add_vector_column(const GeomVertexData *vertex_data, const InternalName *name,
add_vector_column(const GeomVertexDataPipelineReader *data_reader, const InternalName *name,
VectorFunc *func) {
if (vertex_data->has_column(name)) {
GeomVertexReader *reader = new GeomVertexReader(vertex_data, name);
if (data_reader->has_column(name)) {
GeomVertexReader *reader = new GeomVertexReader(data_reader, name);
ComponentSender *sender = NULL;
const GeomVertexColumn *column = reader->get_column();
switch (column->get_num_components()) {
@@ -262,10 +262,10 @@ add_vector_column(const GeomVertexData *vertex_data, const InternalName *name,
// named column doesn't exist in the vertex data).
////////////////////////////////////////////////////////////////////
bool CLP(ImmediateModeSender)::
add_vector_uint_column(const GeomVertexData *vertex_data,
add_vector_uint_column(const GeomVertexDataPipelineReader *data_reader,
const InternalName *name, VectorUintFunc *func) {
if (vertex_data->has_column(name)) {
GeomVertexReader *reader = new GeomVertexReader(vertex_data, name);
if (data_reader->has_column(name)) {
GeomVertexReader *reader = new GeomVertexReader(data_reader, name);
ComponentSender *sender = NULL;
const GeomVertexColumn *column = reader->get_column();
switch (column->get_num_components()) {
@@ -58,17 +58,18 @@ public:
typedef void APIENTRY VectorFunc(GLint, const GLfloat *);
typedef void APIENTRY VectorUintFunc(GLint, const GLuint *);
bool add_column(const GeomVertexData *vertex_data, const InternalName *name,
Func1f *func1f, Func2f *func2f, Func3f *func3f, Func4f *func4f);
bool add_texcoord_column(const GeomVertexData *vertex_data,
bool add_column(const GeomVertexDataPipelineReader *data_reader,
const InternalName *name, Func1f *func1f,
Func2f *func2f, Func3f *func3f, Func4f *func4f);
bool add_texcoord_column(const GeomVertexDataPipelineReader *data_reader,
const InternalName *name, int stage_index,
TexcoordFunc1f *func1f, TexcoordFunc2f *func2f,
TexcoordFunc3f *func3f, TexcoordFunc4f *func4f);
bool add_vector_column(const GeomVertexData *vertex_data, const InternalName *name,
VectorFunc *func);
bool add_vector_uint_column(const GeomVertexData *vertex_data, const InternalName *name,
VectorUintFunc *func);
bool add_vector_column(const GeomVertexDataPipelineReader *data_reader,
const InternalName *name, VectorFunc *func);
bool add_vector_uint_column(const GeomVertexDataPipelineReader *data_reader,
const InternalName *name, VectorUintFunc *func);
void add_sender(ComponentSender *sender);
+10 -16
View File
@@ -419,8 +419,7 @@ bind(GSG *gsg) {
// Description: This function disables a currently-bound shader.
////////////////////////////////////////////////////////////////////
void CLP(ShaderContext)::
unbind()
{
unbind() {
#ifdef HAVE_CGGL
if (_cg_context != 0) {
cgGLDisableProfile(_cg_profile[SHADER_type_vert]);
@@ -445,8 +444,7 @@ unbind()
// transforms.
////////////////////////////////////////////////////////////////////
void CLP(ShaderContext)::
issue_parameters(GSG *gsg, bool altered)
{
issue_parameters(GSG *gsg, bool altered) {
#ifdef HAVE_CGGL
if (_cg_context == 0) {
return;
@@ -482,8 +480,7 @@ issue_parameters(GSG *gsg, bool altered)
// Description: Disable all the vertex arrays used by this shader.
////////////////////////////////////////////////////////////////////
void CLP(ShaderContext)::
disable_shader_vertex_arrays(GSG *gsg)
{
disable_shader_vertex_arrays(GSG *gsg) {
#ifdef HAVE_CGGL
if (_cg_context == 0) {
return;
@@ -508,8 +505,7 @@ disable_shader_vertex_arrays(GSG *gsg)
// reenable them. We may optimize this someday.
////////////////////////////////////////////////////////////////////
void CLP(ShaderContext)::
update_shader_vertex_arrays(CLP(ShaderContext) *prev, GSG *gsg)
{
update_shader_vertex_arrays(CLP(ShaderContext) *prev, GSG *gsg) {
if (prev) prev->disable_shader_vertex_arrays(gsg);
#ifdef HAVE_CGGL
if (_cg_context == 0) {
@@ -522,7 +518,7 @@ update_shader_vertex_arrays(CLP(ShaderContext) *prev, GSG *gsg)
} else
#endif // SUPPORT_IMMEDIATE_MODE
{
const GeomVertexArrayData *array_data;
const GeomVertexArrayDataPipelineReader *array_reader;
Geom::NumericType numeric_type;
int start, stride, num_values;
int nvarying = _var_spec.size();
@@ -543,10 +539,10 @@ update_shader_vertex_arrays(CLP(ShaderContext) *prev, GSG *gsg)
}
}
}
if (gsg->_vertex_data->get_array_info(name,
array_data, num_values, numeric_type,
if (gsg->_data_reader->get_array_info(name,
array_reader, num_values, numeric_type,
start, stride)) {
const unsigned char *client_pointer = gsg->setup_array_data(array_data);
const unsigned char *client_pointer = gsg->setup_array_data(array_reader);
cgGLSetParameterPointer(p,
num_values, gsg->get_numeric_type(numeric_type),
stride, client_pointer + start);
@@ -565,8 +561,7 @@ update_shader_vertex_arrays(CLP(ShaderContext) *prev, GSG *gsg)
// Description: Disable all the texture bindings used by this shader.
////////////////////////////////////////////////////////////////////
void CLP(ShaderContext)::
disable_shader_texture_bindings(GSG *gsg)
{
disable_shader_texture_bindings(GSG *gsg) {
#ifdef HAVE_CGGL
if (_cg_context == 0) {
return;
@@ -602,8 +597,7 @@ disable_shader_texture_bindings(GSG *gsg)
// reenable them. We may optimize this someday.
////////////////////////////////////////////////////////////////////
void CLP(ShaderContext)::
update_shader_texture_bindings(CLP(ShaderContext) *prev, GSG *gsg)
{
update_shader_texture_bindings(CLP(ShaderContext) *prev, GSG *gsg) {
if (prev) prev->disable_shader_texture_bindings(gsg);
#ifdef HAVE_CGGL
if (_cg_context == 0) {
+168
View File
@@ -461,6 +461,174 @@ CData(const Geom::CData &copy) :
{
}
////////////////////////////////////////////////////////////////////
// Function: GeomPipelineReader::Constructor
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
INLINE GeomPipelineReader::
GeomPipelineReader(const Geom *object, int pipeline_stage) :
_object(object),
_pipeline_stage(pipeline_stage),
_cdata(object->_cycler.read_stage(pipeline_stage))
{
nassertv(_object->test_ref_count_nonzero());
#ifdef DO_PIPELINING
nassertv(_cdata->test_ref_count_nonzero());
#endif // DO_PIPELINING
}
////////////////////////////////////////////////////////////////////
// Function: GeomPipelineReader::Copy Constructor
// Access: Private
// Description: Don't attempt to copy these objects.
////////////////////////////////////////////////////////////////////
INLINE GeomPipelineReader::
GeomPipelineReader(const GeomPipelineReader &) {
nassertv(false);
}
////////////////////////////////////////////////////////////////////
// Function: GeomPipelineReader::Copy Assignment Operator
// Access: Private
// Description: Don't attempt to copy these objects.
////////////////////////////////////////////////////////////////////
INLINE void GeomPipelineReader::
operator = (const GeomPipelineReader &) {
nassertv(false);
}
////////////////////////////////////////////////////////////////////
// Function: GeomPipelineReader::Destructor
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
INLINE GeomPipelineReader::
~GeomPipelineReader() {
nassertv(_object->test_ref_count_nonzero());
#ifdef DO_PIPELINING
nassertv(_cdata->test_ref_count_nonzero());
#endif // DO_PIPELINING
_object->_cycler.release_read_stage(_pipeline_stage, _cdata);
_object = NULL;
_cdata = NULL;
}
////////////////////////////////////////////////////////////////////
// Function: GeomPipelineReader::get_object
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
INLINE const Geom *GeomPipelineReader::
get_object() const {
return _object;
}
////////////////////////////////////////////////////////////////////
// Function: GeomPipelineReader::get_pipeline_stage
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
INLINE int GeomPipelineReader::
get_pipeline_stage() const {
return _pipeline_stage;
}
////////////////////////////////////////////////////////////////////
// Function: GeomPipelineReader::check_usage_hint
// Access: Public
// Description: Ensures that the Geom's usage_hint cache has been
// computed.
////////////////////////////////////////////////////////////////////
INLINE void GeomPipelineReader::
check_usage_hint() const {
if (!_cdata->_got_usage_hint) {
((Geom *)_object)->reset_usage_hint((Geom::CData *)_cdata);
}
}
////////////////////////////////////////////////////////////////////
// Function: GeomPipelineReader::get_primitive_type
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
INLINE GeomPipelineReader::PrimitiveType GeomPipelineReader::
get_primitive_type() const {
return _cdata->_primitive_type;
}
////////////////////////////////////////////////////////////////////
// Function: GeomPipelineReader::get_shade_model
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
INLINE GeomPipelineReader::ShadeModel GeomPipelineReader::
get_shade_model() const {
return _cdata->_shade_model;
}
////////////////////////////////////////////////////////////////////
// Function: GeomPipelineReader::get_geom_rendering
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
INLINE int GeomPipelineReader::
get_geom_rendering() const {
return _cdata->_geom_rendering;
}
////////////////////////////////////////////////////////////////////
// Function: GeomPipelineReader::get_usage_hint
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
INLINE GeomPipelineReader::UsageHint GeomPipelineReader::
get_usage_hint() const {
nassertr(_cdata->_got_usage_hint, UH_static);
return _cdata->_usage_hint;
}
////////////////////////////////////////////////////////////////////
// Function: GeomPipelineReader::get_vertex_data
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
INLINE CPT(GeomVertexData) GeomPipelineReader::
get_vertex_data() const {
return _cdata->_data;
}
////////////////////////////////////////////////////////////////////
// Function: GeomPipelineReader::get_num_primitives
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
INLINE int GeomPipelineReader::
get_num_primitives() const {
return _cdata->_primitives.size();
}
////////////////////////////////////////////////////////////////////
// Function: GeomPipelineReader::get_primitive
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
INLINE const GeomPrimitive *GeomPipelineReader::
get_primitive(int i) const {
nassertr(i >= 0 && i < (int)_cdata->_primitives.size(), NULL);
return _cdata->_primitives[i];
}
////////////////////////////////////////////////////////////////////
// Function: GeomPipelineReader::get_modified
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
INLINE UpdateSeq GeomPipelineReader::
get_modified() const {
return _cdata->_modified;
}
INLINE ostream &
operator << (ostream &out, const Geom &obj) {
obj.output(out);
+64 -61
View File
@@ -685,18 +685,11 @@ transform_vertices(const LMatrix4f &mat) {
////////////////////////////////////////////////////////////////////
bool Geom::
check_valid() const {
CDReader cdata(_cycler);
Primitives::const_iterator pi;
for (pi = cdata->_primitives.begin();
pi != cdata->_primitives.end();
++pi) {
if (!(*pi)->check_valid(cdata->_data)) {
return false;
}
}
return true;
int pipeline_stage = Thread::get_current_pipeline_stage();
GeomPipelineReader geom_reader(this, pipeline_stage);
GeomVertexDataPipelineReader data_reader(geom_reader.get_vertex_data(), pipeline_stage);
data_reader.check_array_readers();
return geom_reader.check_valid(&data_reader);
}
////////////////////////////////////////////////////////////////////
@@ -709,18 +702,11 @@ check_valid() const {
////////////////////////////////////////////////////////////////////
bool Geom::
check_valid(const GeomVertexData *vertex_data) const {
CDReader cdata(_cycler);
Primitives::const_iterator pi;
for (pi = cdata->_primitives.begin();
pi != cdata->_primitives.end();
++pi) {
if (!(*pi)->check_valid(vertex_data)) {
return false;
}
}
return true;
int pipeline_stage = Thread::get_current_pipeline_stage();
GeomPipelineReader geom_reader(this, pipeline_stage);
GeomVertexDataPipelineReader data_reader(vertex_data, pipeline_stage);
data_reader.check_array_readers();
return geom_reader.check_valid(&data_reader);
}
////////////////////////////////////////////////////////////////////
@@ -945,21 +931,14 @@ prepare_now(PreparedGraphicsObjects *prepared_objects,
void Geom::
draw(GraphicsStateGuardianBase *gsg, const GeomMunger *munger,
const GeomVertexData *vertex_data) const {
CDReader cdata(_cycler);
int pipeline_stage = Thread::get_current_pipeline_stage();
GeomPipelineReader geom_reader(this, pipeline_stage);
geom_reader.check_usage_hint();
#ifdef DO_PIPELINING
// Make sure the usage_hint is already updated before we start to
// draw, so we don't end up with a circular lock if the GSG asks us
// to update this while we're holding the read lock.
if (!cdata->_got_usage_hint) {
{
CDWriter cdataw(((Geom *)this)->_cycler, cdata, false);
((Geom *)this)->reset_usage_hint(cdataw);
do_draw(gsg, munger, vertex_data, cdataw);
}
} else
#endif // DO_PIPELINING
do_draw(gsg, munger, vertex_data, cdata);
GeomVertexDataPipelineReader data_reader(vertex_data, pipeline_stage);
data_reader.check_array_readers();
geom_reader.draw(gsg, munger, &data_reader);
}
////////////////////////////////////////////////////////////////////
@@ -1083,29 +1062,6 @@ check_will_be_valid(const GeomVertexData *vertex_data) const {
return true;
}
////////////////////////////////////////////////////////////////////
// Function: Geom::do_draw
// Access: Private
// Description: The private implementation of draw().
////////////////////////////////////////////////////////////////////
void Geom::
do_draw(GraphicsStateGuardianBase *gsg, const GeomMunger *munger,
const GeomVertexData *vertex_data, const Geom::CData *cdata) const {
PStatTimer timer(_draw_primitive_setup_pcollector);
if (gsg->begin_draw_primitives(this, munger, vertex_data)) {
Primitives::const_iterator pi;
for (pi = cdata->_primitives.begin();
pi != cdata->_primitives.end();
++pi) {
const GeomPrimitive *primitive = (*pi);
if (primitive->get_num_vertices() != 0) {
(*pi)->draw(gsg);
}
}
gsg->end_draw_primitives();
}
}
////////////////////////////////////////////////////////////////////
// Function: Geom::reset_usage_hint
@@ -1374,3 +1330,50 @@ fillin(DatagramIterator &scan, BamReader *manager) {
_got_usage_hint = false;
_modified = Geom::get_next_modified();
}
////////////////////////////////////////////////////////////////////
// Function: GeomPipelineReader::check_valid
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
bool GeomPipelineReader::
check_valid(const GeomVertexDataPipelineReader *data_reader) const {
Geom::Primitives::const_iterator pi;
for (pi = _cdata->_primitives.begin();
pi != _cdata->_primitives.end();
++pi) {
const GeomPrimitive *primitive = (*pi);
GeomPrimitivePipelineReader reader(primitive, _pipeline_stage);
reader.check_minmax();
if (!reader.check_valid(data_reader)) {
return false;
}
}
return true;
}
////////////////////////////////////////////////////////////////////
// Function: GeomPipelineReader::draw
// Access: Public
// Description: The implementation of Geom::draw().
////////////////////////////////////////////////////////////////////
void GeomPipelineReader::
draw(GraphicsStateGuardianBase *gsg, const GeomMunger *munger,
const GeomVertexDataPipelineReader *data_reader) const {
PStatTimer timer(Geom::_draw_primitive_setup_pcollector);
if (gsg->begin_draw_primitives(this, munger, data_reader)) {
Geom::Primitives::const_iterator pi;
for (pi = _cdata->_primitives.begin();
pi != _cdata->_primitives.end();
++pi) {
const GeomPrimitive *primitive = (*pi);
GeomPrimitivePipelineReader reader(primitive, _pipeline_stage);
if (reader.get_num_vertices() != 0) {
reader.check_minmax();
primitive->draw(gsg, &reader);
}
}
gsg->end_draw_primitives();
}
}
+43 -5
View File
@@ -156,11 +156,6 @@ private:
void clear_prepared(PreparedGraphicsObjects *prepared_objects);
bool check_will_be_valid(const GeomVertexData *vertex_data) const;
void do_draw(GraphicsStateGuardianBase *gsg,
const GeomMunger *munger,
const GeomVertexData *vertex_data,
const CData *cdata) const;
void reset_usage_hint(CData *cdata);
void reset_geom_rendering(CData *cdata);
@@ -296,9 +291,52 @@ private:
friend class CacheEntry;
friend class GeomMunger;
friend class GeomContext;
friend class GeomPipelineReader;
friend class PreparedGraphicsObjects;
};
////////////////////////////////////////////////////////////////////
// Class : GeomPipelineReader
// Description : Encapsulates the data from a Geom,
// pre-fetched for one stage of the pipeline.
////////////////////////////////////////////////////////////////////
class EXPCL_PANDA GeomPipelineReader : public GeomEnums {
public:
INLINE GeomPipelineReader(const Geom *object, int pipeline_stage);
private:
INLINE GeomPipelineReader(const GeomPipelineReader &copy);
INLINE void operator = (const GeomPipelineReader &copy);
public:
INLINE ~GeomPipelineReader();
ALLOC_DELETED_CHAIN(GeomPipelineReader);
INLINE const Geom *get_object() const;
INLINE int get_pipeline_stage() const;
INLINE void check_usage_hint() const;
INLINE PrimitiveType get_primitive_type() const;
INLINE ShadeModel get_shade_model() const;
INLINE int get_geom_rendering() const;
INLINE UsageHint get_usage_hint() const;
INLINE CPT(GeomVertexData) get_vertex_data() const;
INLINE int get_num_primitives() const;
INLINE const GeomPrimitive *get_primitive(int i) const;
INLINE UpdateSeq get_modified() const;
bool check_valid(const GeomVertexDataPipelineReader *data_reader) const;
void draw(GraphicsStateGuardianBase *gsg, const GeomMunger *munger,
const GeomVertexDataPipelineReader *data_reader) const;
private:
const Geom *_object;
int _pipeline_stage;
const Geom::CData *_cdata;
};
INLINE ostream &operator << (ostream &out, const Geom &obj);
#include "geom.I"
+2 -2
View File
@@ -35,8 +35,8 @@ PStatCollector GeomCacheManager::_geom_cache_evict_pcollector("Geom cache operat
////////////////////////////////////////////////////////////////////
GeomCacheManager::
GeomCacheManager() :
_total_size(0),
_lock("GeomCacheManager")
_lock("GeomCacheManager"),
_total_size(0)
{
// We deliberately hang on to this pointer forever.
_list = new GeomCacheEntry;
+2 -2
View File
@@ -117,8 +117,8 @@ get_min_num_vertices_per_primitive() const {
// primitive.
////////////////////////////////////////////////////////////////////
void GeomLines::
draw(GraphicsStateGuardianBase *gsg) const {
gsg->draw_lines(this);
draw(GraphicsStateGuardianBase *gsg, const GeomPrimitivePipelineReader *reader) const {
gsg->draw_lines(reader);
}
////////////////////////////////////////////////////////////////////
+2 -1
View File
@@ -40,7 +40,8 @@ public:
virtual int get_min_num_vertices_per_primitive() const;
public:
virtual void draw(GraphicsStateGuardianBase *gsg) const;
virtual void draw(GraphicsStateGuardianBase *gsg,
const GeomPrimitivePipelineReader *reader) const;
protected:
virtual CPT(GeomVertexArrayData) rotate_impl() const;
+2 -2
View File
@@ -117,8 +117,8 @@ get_min_num_vertices_per_primitive() const {
// primitive.
////////////////////////////////////////////////////////////////////
void GeomLinestrips::
draw(GraphicsStateGuardianBase *gsg) const {
gsg->draw_linestrips(this);
draw(GraphicsStateGuardianBase *gsg, const GeomPrimitivePipelineReader *reader) const {
gsg->draw_linestrips(reader);
}
////////////////////////////////////////////////////////////////////
+2 -1
View File
@@ -39,7 +39,8 @@ public:
virtual int get_min_num_vertices_per_primitive() const;
public:
virtual void draw(GraphicsStateGuardianBase *gsg) const;
virtual void draw(GraphicsStateGuardianBase *gsg,
const GeomPrimitivePipelineReader *reader) const;
protected:
virtual CPT(GeomPrimitive) decompose_impl() const;
+2 -2
View File
@@ -134,8 +134,8 @@ get_min_num_vertices_per_primitive() const {
// primitive.
////////////////////////////////////////////////////////////////////
void GeomPoints::
draw(GraphicsStateGuardianBase *gsg) const {
gsg->draw_points(this);
draw(GraphicsStateGuardianBase *gsg, const GeomPrimitivePipelineReader *reader) const {
gsg->draw_points(reader);
}
////////////////////////////////////////////////////////////////////
+2 -1
View File
@@ -41,7 +41,8 @@ public:
virtual int get_min_num_vertices_per_primitive() const;
public:
virtual void draw(GraphicsStateGuardianBase *gsg) const;
virtual void draw(GraphicsStateGuardianBase *gsg,
const GeomPrimitivePipelineReader *reader) const;
public:
static void register_with_read_factory();
+281 -42
View File
@@ -111,8 +111,23 @@ is_composite() const {
////////////////////////////////////////////////////////////////////
INLINE bool GeomPrimitive::
is_indexed() const {
CDReader cdata(_cycler);
return (cdata->_vertices != (GeomVertexArrayData *)NULL);
GeomPrimitivePipelineReader reader(this, Thread::get_current_pipeline_stage());
return reader.is_indexed();
}
////////////////////////////////////////////////////////////////////
// Function: GeomPrimitive::get_first_vertex
// Access: Published
// Description: Returns the first vertex number referenced by the
// primitive. This is particularly important in the
// case of a nonindexed primitive, in which case
// get_first_vertex() and get_num_vertices() completely
// define the extent of the vertex range.
////////////////////////////////////////////////////////////////////
INLINE int GeomPrimitive::
get_first_vertex() const {
GeomPrimitivePipelineReader reader(this, Thread::get_current_pipeline_stage());
return reader.get_first_vertex();
}
////////////////////////////////////////////////////////////////////
@@ -123,12 +138,32 @@ is_indexed() const {
////////////////////////////////////////////////////////////////////
INLINE int GeomPrimitive::
get_num_vertices() const {
CDReader cdata(_cycler);
if (cdata->_vertices == (GeomVertexArrayData *)NULL) {
return cdata->_num_vertices;
} else {
return cdata->_vertices->get_num_rows();
}
GeomPrimitivePipelineReader reader(this, Thread::get_current_pipeline_stage());
return reader.get_num_vertices();
}
////////////////////////////////////////////////////////////////////
// Function: GeomPrimitive::get_vertex
// Access: Published
// Description: Returns the ith vertex index in the table.
////////////////////////////////////////////////////////////////////
INLINE int GeomPrimitive::
get_vertex(int i) const {
GeomPrimitivePipelineReader reader(this, Thread::get_current_pipeline_stage());
return reader.get_vertex(i);
}
////////////////////////////////////////////////////////////////////
// Function: GeomPrimitive::get_num_primitives
// Access: Published
// Description: Returns the number of individual primitives stored
// within this object. All primitives are the same
// type.
////////////////////////////////////////////////////////////////////
INLINE int GeomPrimitive::
get_num_primitives() const {
GeomPrimitivePipelineReader reader(this, Thread::get_current_pipeline_stage());
return reader.get_num_primitives();
}
////////////////////////////////////////////////////////////////////
@@ -179,14 +214,9 @@ get_primitive_num_faces(int n) const {
////////////////////////////////////////////////////////////////////
INLINE int GeomPrimitive::
get_min_vertex() const {
CDReader cdata(_cycler);
if (!cdata->_got_minmax) {
CDWriter cdataw(((GeomPrimitive *)this)->_cycler, cdata, false);
((GeomPrimitive *)this)->recompute_minmax(cdataw);
return cdataw->_min_vertex;
}
return cdata->_min_vertex;
GeomPrimitivePipelineReader reader(this, Thread::get_current_pipeline_stage());
reader.check_minmax();
return reader.get_min_vertex();
}
////////////////////////////////////////////////////////////////////
@@ -197,13 +227,9 @@ get_min_vertex() const {
////////////////////////////////////////////////////////////////////
INLINE int GeomPrimitive::
get_max_vertex() const {
CDReader cdata(_cycler);
if (!cdata->_got_minmax) {
CDWriter cdataw(((GeomPrimitive *)this)->_cycler, cdata, false);
((GeomPrimitive *)this)->recompute_minmax(cdataw);
return cdataw->_max_vertex;
}
return cdata->_max_vertex;
GeomPrimitivePipelineReader reader(this, Thread::get_current_pipeline_stage());
reader.check_minmax();
return reader.get_max_vertex();
}
////////////////////////////////////////////////////////////////////
@@ -231,6 +257,24 @@ get_modified() const {
return cdata->_modified;
}
////////////////////////////////////////////////////////////////////
// Function: GeomPrimitive::check_valid
// Access: Published
// Description: Verifies that the primitive only references vertices
// that actually exist within the indicated
// GeomVertexData. Returns true if the primitive
// appears to be valid, false otherwise.
////////////////////////////////////////////////////////////////////
INLINE bool GeomPrimitive::
check_valid(const GeomVertexData *vertex_data) const {
int pipeline_stage = Thread::get_current_pipeline_stage();
GeomPrimitivePipelineReader reader(this, pipeline_stage);
reader.check_minmax();
GeomVertexDataPipelineReader data_reader(vertex_data, pipeline_stage);
data_reader.check_array_readers();
return reader.check_valid(&data_reader);
}
////////////////////////////////////////////////////////////////////
// Function: GeomPrimitive::get_vertices
// Access: Public
@@ -255,8 +299,8 @@ get_vertices() const {
////////////////////////////////////////////////////////////////////
INLINE int GeomPrimitive::
get_index_stride() const {
nassertr(is_indexed(), 0);
return get_vertices()->get_array_format()->get_stride();
GeomPrimitivePipelineReader reader(this, Thread::get_current_pipeline_stage());
return reader.get_index_stride();
}
////////////////////////////////////////////////////////////////////
@@ -302,14 +346,9 @@ get_ends() const {
////////////////////////////////////////////////////////////////////
INLINE const GeomVertexArrayData *GeomPrimitive::
get_mins() const {
nassertr(is_indexed(), NULL);
CDReader cdata(_cycler);
if (!cdata->_got_minmax) {
CDWriter cdataw(((GeomPrimitive *)this)->_cycler, cdata, false);
((GeomPrimitive *)this)->recompute_minmax(cdataw);
return cdataw->_mins;
}
return cdata->_mins;
GeomPrimitivePipelineReader reader(this, Thread::get_current_pipeline_stage());
reader.check_minmax();
return reader.get_mins();
}
////////////////////////////////////////////////////////////////////
@@ -325,14 +364,9 @@ get_mins() const {
////////////////////////////////////////////////////////////////////
INLINE const GeomVertexArrayData *GeomPrimitive::
get_maxs() const {
nassertr(is_indexed(), NULL);
CDReader cdata(_cycler);
if (!cdata->_got_minmax) {
CDWriter cdataw(((GeomPrimitive *)this)->_cycler, cdata, false);
((GeomPrimitive *)this)->recompute_minmax(cdataw);
return cdataw->_maxs;
}
return cdata->_maxs;
GeomPrimitivePipelineReader reader(this, Thread::get_current_pipeline_stage());
reader.check_minmax();
return reader.get_maxs();
}
////////////////////////////////////////////////////////////////////
@@ -381,7 +415,7 @@ INLINE CPT(GeomVertexArrayFormat) GeomPrimitive::
get_index_format() const {
return GeomVertexArrayFormat::register_format
(new GeomVertexArrayFormat(InternalName::get_index(), 1,
get_index_type(), C_index));
get_index_type(), C_index));
}
////////////////////////////////////////////////////////////////////
@@ -435,6 +469,211 @@ CData(const GeomPrimitive::CData &copy) :
{
}
////////////////////////////////////////////////////////////////////
// Function: GeomPrimitivePipelineReader::Copy Constructor
// Access: Private
// Description: Don't attempt to copy these objects.
////////////////////////////////////////////////////////////////////
INLINE GeomPrimitivePipelineReader::
GeomPrimitivePipelineReader(const GeomPrimitivePipelineReader &) {
nassertv(false);
}
////////////////////////////////////////////////////////////////////
// Function: GeomPrimitivePipelineReader::Copy Assignment Operator
// Access: Private
// Description: Don't attempt to copy these objects.
////////////////////////////////////////////////////////////////////
INLINE void GeomPrimitivePipelineReader::
operator = (const GeomPrimitivePipelineReader &) {
nassertv(false);
}
////////////////////////////////////////////////////////////////////
// Function: GeomPrimitivePipelineReader::get_object
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
INLINE const GeomPrimitive *GeomPrimitivePipelineReader::
get_object() const {
return _object;
}
////////////////////////////////////////////////////////////////////
// Function: GeomPrimitivePipelineReader::get_pipeline_stage
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
INLINE int GeomPrimitivePipelineReader::
get_pipeline_stage() const {
return _pipeline_stage;
}
////////////////////////////////////////////////////////////////////
// Function: GeomPrimitivePipelineReader::check_minmax
// Access: Public
// Description: Ensures that the primitive's minmax cache has been
// computed.
////////////////////////////////////////////////////////////////////
INLINE void GeomPrimitivePipelineReader::
check_minmax() const {
if (!_cdata->_got_minmax) {
((GeomPrimitive *)_object)->recompute_minmax((GeomPrimitive::CData *)_cdata);
}
}
////////////////////////////////////////////////////////////////////
// Function: GeomPrimitivePipelineReader::get_shade_model
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
INLINE GeomPrimitivePipelineReader::ShadeModel GeomPrimitivePipelineReader::
get_shade_model() const {
return _cdata->_shade_model;
}
////////////////////////////////////////////////////////////////////
// Function: GeomPrimitivePipelineReader::get_usage_hint
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
INLINE GeomPrimitivePipelineReader::UsageHint GeomPrimitivePipelineReader::
get_usage_hint() const {
return _cdata->_usage_hint;
}
////////////////////////////////////////////////////////////////////
// Function: GeomPrimitivePipelineReader::get_index_type
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
INLINE GeomPrimitivePipelineReader::NumericType GeomPrimitivePipelineReader::
get_index_type() const {
return _cdata->_index_type;
}
////////////////////////////////////////////////////////////////////
// Function: GeomPrimitivePipelineReader::is_indexed
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
INLINE bool GeomPrimitivePipelineReader::
is_indexed() const {
return (_cdata->_vertices != (GeomVertexArrayData *)NULL);
}
////////////////////////////////////////////////////////////////////
// Function: GeomPrimitivePipelineReader::get_num_vertices
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
INLINE int GeomPrimitivePipelineReader::
get_num_vertices() const {
if (_cdata->_vertices == (GeomVertexArrayData *)NULL) {
return _cdata->_num_vertices;
} else {
return _vertices_reader->get_num_rows();
}
}
////////////////////////////////////////////////////////////////////
// Function: GeomPrimitivePipelineReader::get_min_vertex
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
INLINE int GeomPrimitivePipelineReader::
get_min_vertex() const {
nassertr(_cdata->_got_minmax, 0);
return _cdata->_min_vertex;
}
////////////////////////////////////////////////////////////////////
// Function: GeomPrimitivePipelineReader::get_max_vertex
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
INLINE int GeomPrimitivePipelineReader::
get_max_vertex() const {
nassertr(_cdata->_got_minmax, 0);
return _cdata->_max_vertex;
}
////////////////////////////////////////////////////////////////////
// Function: GeomPrimitivePipelineReader::get_data_size_bytes
// Access: Published
// Description: Returns the number of bytes stored in the vertices
// array.
////////////////////////////////////////////////////////////////////
INLINE int GeomPrimitivePipelineReader::
get_data_size_bytes() const {
return _vertices_reader->get_data_size_bytes();
}
////////////////////////////////////////////////////////////////////
// Function: GeomPrimitivePipelineReader::get_modified
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
INLINE UpdateSeq GeomPrimitivePipelineReader::
get_modified() const {
return _cdata->_modified;
}
////////////////////////////////////////////////////////////////////
// Function: GeomPrimitivePipelineReader::get_index_stride
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
INLINE int GeomPrimitivePipelineReader::
get_index_stride() const {
nassertr(is_indexed(), 0);
return _cdata->_vertices->get_array_format()->get_stride();
}
////////////////////////////////////////////////////////////////////
// Function: GeomPrimitivePipelineReader::get_data
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
INLINE CPTA_uchar GeomPrimitivePipelineReader::
get_data() const {
return _vertices_reader->get_data();
}
////////////////////////////////////////////////////////////////////
// Function: GeomPrimitivePipelineReader::get_ends
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
INLINE CPTA_int GeomPrimitivePipelineReader::
get_ends() const {
return _cdata->_ends;
}
////////////////////////////////////////////////////////////////////
// Function: GeomPrimitivePipelineReader::get_mins
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
INLINE const GeomVertexArrayData *GeomPrimitivePipelineReader::
get_mins() const {
nassertr(is_indexed(), NULL);
nassertr(_cdata->_got_minmax, NULL);
return _cdata->_mins;
}
////////////////////////////////////////////////////////////////////
// Function: GeomPrimitivePipelineReader::get_maxs
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
INLINE const GeomVertexArrayData *GeomPrimitivePipelineReader::
get_maxs() const {
nassertr(is_indexed(), NULL);
nassertr(_cdata->_got_minmax, NULL);
return _cdata->_maxs;
}
INLINE ostream &
operator << (ostream &out, const GeomPrimitive &obj) {
obj.output(out);
+118 -84
View File
@@ -170,51 +170,6 @@ set_index_type(GeomPrimitive::NumericType index_type) {
}
}
////////////////////////////////////////////////////////////////////
// Function: GeomPrimitive::get_first_vertex
// Access: Published
// Description: Returns the first vertex number referenced by the
// primitive. This is particularly important in the
// case of a nonindexed primitive, in which case
// get_first_vertex() and get_num_vertices() completely
// define the extent of the vertex range.
////////////////////////////////////////////////////////////////////
int GeomPrimitive::
get_first_vertex() const {
CDReader cdata(_cycler);
if (cdata->_vertices == (GeomVertexArrayData *)NULL) {
return cdata->_first_vertex;
} else if (cdata->_vertices->get_num_rows() == 0) {
return 0;
} else {
GeomVertexReader index(cdata->_vertices, 0);
return index.get_data1i();
}
}
////////////////////////////////////////////////////////////////////
// Function: GeomPrimitive::get_vertex
// Access: Published
// Description: Returns the ith vertex index in the table.
////////////////////////////////////////////////////////////////////
int GeomPrimitive::
get_vertex(int i) const {
CDReader cdata(_cycler);
if (cdata->_vertices != (GeomVertexArrayData *)NULL) {
// The indexed case.
nassertr(i >= 0 && i < (int)cdata->_vertices->get_num_rows(), -1);
GeomVertexReader index(cdata->_vertices, 0);
index.set_row(i);
return index.get_data1i();
} else {
// The nonindexed case.
return cdata->_first_vertex + i;
}
}
////////////////////////////////////////////////////////////////////
// Function: GeomPrimitive::add_vertex
// Access: Published
@@ -545,30 +500,6 @@ make_indexed() {
do_make_indexed(cdata);
}
////////////////////////////////////////////////////////////////////
// Function: GeomPrimitive::get_num_primitives
// Access: Published
// Description: Returns the number of individual primitives stored
// within this object. All primitives are the same
// type.
////////////////////////////////////////////////////////////////////
int GeomPrimitive::
get_num_primitives() const {
int num_vertices_per_primitive = get_num_vertices_per_primitive();
CDReader cdata(_cycler);
if (num_vertices_per_primitive == 0) {
// This is a complex primitive type like a triangle strip: each
// primitive uses a different number of vertices.
return cdata->_ends.size();
} else {
// This is a simple primitive type like a triangle: each primitive
// uses the same number of vertices.
return (get_num_vertices() / num_vertices_per_primitive);
}
}
////////////////////////////////////////////////////////////////////
// Function: GeomPrimitive::get_primitive_start
// Access: Published
@@ -833,20 +764,6 @@ get_num_bytes() const {
return num_bytes;
}
////////////////////////////////////////////////////////////////////
// Function: GeomPrimitive::check_valid
// Access: Published
// Description: Verifies that the primitive only references vertices
// that actually exist within the indicated
// GeomVertexData. Returns true if the primitive
// appears to be valid, false otherwise.
////////////////////////////////////////////////////////////////////
bool GeomPrimitive::
check_valid(const GeomVertexData *vertex_data) const {
return get_num_vertices() == 0 ||
get_max_vertex() < vertex_data->get_num_rows();
}
////////////////////////////////////////////////////////////////////
// Function: GeomPrimitive::output
// Access: Published, Virtual
@@ -969,6 +886,8 @@ set_nonindexed_vertices(int first_vertex, int num_vertices) {
cdata->_modified = Geom::get_next_modified();
cdata->_got_minmax = false;
// Force the minmax to be recomputed.
recompute_minmax(cdata);
}
@@ -1357,7 +1276,7 @@ append_unused_vertices(GeomVertexArrayData *, int) {
// necessary.
////////////////////////////////////////////////////////////////////
void GeomPrimitive::
recompute_minmax(CData *cdata) {
recompute_minmax(GeomPrimitive::CData *cdata) {
if (cdata->_vertices == (GeomVertexArrayData *)NULL) {
// In the nonindexed case, we don't need to do much (the
// minmax is trivial).
@@ -1563,3 +1482,118 @@ fillin(DatagramIterator &scan, BamReader *manager) {
_modified = Geom::get_next_modified();
_got_minmax = false;
}
////////////////////////////////////////////////////////////////////
// Function: GeomPrimitivePipelineReader::Constructor
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
GeomPrimitivePipelineReader::
GeomPrimitivePipelineReader(const GeomPrimitive *object,
int pipeline_stage) :
_object(object),
_pipeline_stage(pipeline_stage),
_cdata(object->_cycler.read_stage(pipeline_stage)),
_vertices_reader(NULL)
{
nassertv(_object->test_ref_count_nonzero());
#ifdef DO_PIPELINING
nassertv(_cdata->test_ref_count_nonzero());
#endif // DO_PIPELINING
if (_cdata->_vertices != (GeomVertexArrayData *)NULL) {
_vertices_reader =
new GeomVertexArrayDataPipelineReader(_cdata->_vertices, _pipeline_stage);
nassertv(_vertices_reader->get_object() == _cdata->_vertices);
}
}
////////////////////////////////////////////////////////////////////
// Function: GeomPrimitivePipelineReader::Destructor
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
GeomPrimitivePipelineReader::
~GeomPrimitivePipelineReader() {
if (_vertices_reader != (GeomVertexArrayDataPipelineReader *)NULL) {
nassertv(_vertices_reader->get_object() == _cdata->_vertices);
delete _vertices_reader;
_vertices_reader = NULL;
}
nassertv(_object->test_ref_count_nonzero());
#ifdef DO_PIPELINING
nassertv(_cdata->test_ref_count_nonzero());
#endif // DO_PIPELINING
_object->_cycler.release_read_stage(_pipeline_stage, _cdata);
_object = NULL;
_cdata = NULL;
}
////////////////////////////////////////////////////////////////////
// Function: GeomPrimitivePipelineReader::get_first_vertex
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
int GeomPrimitivePipelineReader::
get_first_vertex() const {
if (_cdata->_vertices == (GeomVertexArrayData *)NULL) {
return _cdata->_first_vertex;
} else if (_vertices_reader->get_num_rows() == 0) {
return 0;
} else {
GeomVertexReader index(_cdata->_vertices, 0);
return index.get_data1i();
}
}
////////////////////////////////////////////////////////////////////
// Function: GeomPrimitivePipelineReader::get_vertex
// Access: Public
// Description: Returns the ith vertex index in the table.
////////////////////////////////////////////////////////////////////
int GeomPrimitivePipelineReader::
get_vertex(int i) const {
if (_cdata->_vertices != (GeomVertexArrayData *)NULL) {
// The indexed case.
nassertr(i >= 0 && i < _vertices_reader->get_num_rows(), -1);
GeomVertexReader index(_cdata->_vertices, 0);
index.set_row(i);
return index.get_data1i();
} else {
// The nonindexed case.
return _cdata->_first_vertex + i;
}
}
////////////////////////////////////////////////////////////////////
// Function: GeomPrimitivePipelineReader::get_num_primitives
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
int GeomPrimitivePipelineReader::
get_num_primitives() const {
int num_vertices_per_primitive = _object->get_num_vertices_per_primitive();
if (num_vertices_per_primitive == 0) {
// This is a complex primitive type like a triangle strip: each
// primitive uses a different number of vertices.
return _cdata->_ends.size();
} else {
// This is a simple primitive type like a triangle: each primitive
// uses the same number of vertices.
return (get_num_vertices() / num_vertices_per_primitive);
}
}
////////////////////////////////////////////////////////////////////
// Function: GeomPrimitivePipelineReader::check_valid
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
bool GeomPrimitivePipelineReader::
check_valid(const GeomVertexDataPipelineReader *data_reader) const {
return get_num_vertices() == 0 ||
get_max_vertex() < data_reader->get_num_rows();
}
+67 -9
View File
@@ -22,6 +22,7 @@
#include "pandabase.h"
#include "geomEnums.h"
#include "geomVertexArrayData.h"
#include "geomVertexData.h"
#include "typedWritableReferenceCount.h"
#include "luse.h"
#include "updateSeq.h"
@@ -31,14 +32,16 @@
#include "cycleData.h"
#include "cycleDataReader.h"
#include "cycleDataWriter.h"
#include "cycleDataStageReader.h"
#include "cycleDataStageWriter.h"
#include "pipelineCycler.h"
#include "deletedChain.h"
class GeomVertexData;
class PreparedGraphicsObjects;
class IndexBufferContext;
class GraphicsStateGuardianBase;
class FactoryParams;
class GeomPrimitivePipelineReader;
////////////////////////////////////////////////////////////////////
// Class : GeomPrimitive
@@ -95,9 +98,9 @@ PUBLISHED:
INLINE bool is_composite() const;
INLINE bool is_indexed() const;
int get_first_vertex() const;
INLINE int get_first_vertex() const;
INLINE int get_num_vertices() const;
int get_vertex(int i) const;
INLINE int get_vertex(int i) const;
void add_vertex(int vertex);
INLINE void add_vertices(int v1, int v2);
INLINE void add_vertices(int v1, int v2, int v3);
@@ -111,7 +114,7 @@ PUBLISHED:
void pack_vertices(GeomVertexData *dest, const GeomVertexData *source);
void make_indexed();
int get_num_primitives() const;
INLINE int get_num_primitives() const;
int get_primitive_start(int n) const;
int get_primitive_end(int n) const;
int get_primitive_num_vertices(int n) const;
@@ -132,7 +135,7 @@ PUBLISHED:
INLINE int get_data_size_bytes() const;
INLINE UpdateSeq get_modified() const;
bool check_valid(const GeomVertexData *vertex_data) const;
INLINE bool check_valid(const GeomVertexData *vertex_data) const;
virtual void output(ostream &out) const;
virtual void write(ostream &out, int indent_level) const;
@@ -183,7 +186,8 @@ private:
void clear_prepared(PreparedGraphicsObjects *prepared_objects);
public:
virtual void draw(GraphicsStateGuardianBase *gsg) const=0;
virtual void draw(GraphicsStateGuardianBase *gsg,
const GeomPrimitivePipelineReader *reader) const=0;
void calc_tight_bounds(LPoint3f &min_point, LPoint3f &max_point,
bool &found_any,
@@ -218,6 +222,7 @@ private:
INLINE CData();
INLINE CData(const CData &copy);
ALLOC_DELETED_CHAIN(CData);
virtual CycleData *make_copy() const;
virtual void write_datagram(BamWriter *manager, Datagram &dg) const;
virtual int complete_pointers(TypedWritable **plist, BamReader *manager);
@@ -225,7 +230,7 @@ private:
virtual TypeHandle get_parent_type() const {
return GeomPrimitive::get_class_type();
}
ShadeModel _shade_model;
int _first_vertex;
int _num_vertices;
@@ -236,16 +241,21 @@ private:
PT(GeomVertexArrayData) _mins;
PT(GeomVertexArrayData) _maxs;
UpdateSeq _modified;
bool _got_minmax;
unsigned int _min_vertex;
unsigned int _max_vertex;
friend class GeomPrimitive;
};
PipelineCycler<CData> _cycler;
typedef CycleDataReader<CData> CDReader;
typedef CycleDataWriter<CData> CDWriter;
typedef CycleDataStageReader<CData> CDStageReader;
typedef CycleDataStageWriter<CData> CDStageWriter;
private:
static PStatCollector _decompose_pcollector;
static PStatCollector _rotate_pcollector;
@@ -276,6 +286,54 @@ private:
friend class Geom;
friend class PreparedGraphicsObjects;
friend class GeomPrimitivePipelineReader;
};
////////////////////////////////////////////////////////////////////
// Class : GeomPrimitivePipelineReader
// Description : Encapsulates the data from a GeomPrimitive,
// pre-fetched for one stage of the pipeline.
////////////////////////////////////////////////////////////////////
class EXPCL_PANDA GeomPrimitivePipelineReader : public GeomEnums {
public:
GeomPrimitivePipelineReader(const GeomPrimitive *object, int pipeline_stage);
private:
INLINE GeomPrimitivePipelineReader(const GeomPrimitivePipelineReader &copy);
INLINE void operator = (const GeomPrimitivePipelineReader &copy);
public:
~GeomPrimitivePipelineReader();
ALLOC_DELETED_CHAIN(GeomPrimitivePipelineReader);
INLINE const GeomPrimitive *get_object() const;
INLINE int get_pipeline_stage() const;
INLINE void check_minmax() const;
INLINE ShadeModel get_shade_model() const;
INLINE UsageHint get_usage_hint() const;
INLINE NumericType get_index_type() const;
INLINE bool is_indexed() const;
int get_first_vertex() const;
INLINE int get_num_vertices() const;
int get_vertex(int i) const;
int get_num_primitives() const;
INLINE int get_min_vertex() const;
INLINE int get_max_vertex() const;
INLINE int get_data_size_bytes() const;
INLINE UpdateSeq get_modified() const;
bool check_valid(const GeomVertexDataPipelineReader *data_reader) const;
INLINE int get_index_stride() const;
INLINE CPTA_uchar get_data() const;
INLINE CPTA_int get_ends() const;
INLINE const GeomVertexArrayData *get_mins() const;
INLINE const GeomVertexArrayData *get_maxs() const;
private:
const GeomPrimitive *_object;
int _pipeline_stage;
const GeomPrimitive::CData *_cdata;
GeomVertexArrayDataPipelineReader *_vertices_reader;
};
INLINE ostream &operator << (ostream &out, const GeomPrimitive &obj);
+2 -2
View File
@@ -105,8 +105,8 @@ get_num_vertices_per_primitive() const {
// primitive.
////////////////////////////////////////////////////////////////////
void GeomTriangles::
draw(GraphicsStateGuardianBase *gsg) const {
gsg->draw_triangles(this);
draw(GraphicsStateGuardianBase *gsg, const GeomPrimitivePipelineReader *reader) const {
gsg->draw_triangles(reader);
}
////////////////////////////////////////////////////////////////////
+2 -1
View File
@@ -39,7 +39,8 @@ public:
virtual int get_num_vertices_per_primitive() const;
public:
virtual void draw(GraphicsStateGuardianBase *gsg) const;
virtual void draw(GraphicsStateGuardianBase *gsg,
const GeomPrimitivePipelineReader *reader) const;
protected:
virtual CPT(GeomVertexArrayData) rotate_impl() const;
+2 -2
View File
@@ -105,8 +105,8 @@ get_geom_rendering() const {
// primitive.
////////////////////////////////////////////////////////////////////
void GeomTrifans::
draw(GraphicsStateGuardianBase *gsg) const {
gsg->draw_trifans(this);
draw(GraphicsStateGuardianBase *gsg, const GeomPrimitivePipelineReader *reader) const {
gsg->draw_trifans(reader);
}
////////////////////////////////////////////////////////////////////
+2 -1
View File
@@ -38,7 +38,8 @@ public:
virtual int get_geom_rendering() const;
public:
virtual void draw(GraphicsStateGuardianBase *gsg) const;
virtual void draw(GraphicsStateGuardianBase *gsg,
const GeomPrimitivePipelineReader *reader) const;
protected:
virtual CPT(GeomPrimitive) decompose_impl() const;
+2 -2
View File
@@ -120,8 +120,8 @@ get_num_unused_vertices_per_primitive() const {
// primitive.
////////////////////////////////////////////////////////////////////
void GeomTristrips::
draw(GraphicsStateGuardianBase *gsg) const {
gsg->draw_tristrips(this);
draw(GraphicsStateGuardianBase *gsg, const GeomPrimitivePipelineReader *reader) const {
gsg->draw_tristrips(reader);
}
////////////////////////////////////////////////////////////////////
+2 -1
View File
@@ -39,7 +39,8 @@ public:
virtual int get_num_unused_vertices_per_primitive() const;
public:
virtual void draw(GraphicsStateGuardianBase *gsg) const;
virtual void draw(GraphicsStateGuardianBase *gsg,
const GeomPrimitivePipelineReader *reader) const;
protected:
virtual CPT(GeomPrimitive) decompose_impl() const;
+278 -1
View File
@@ -62,7 +62,35 @@ has_column(const InternalName *name) const {
////////////////////////////////////////////////////////////////////
INLINE int GeomVertexArrayData::
get_num_rows() const {
return get_data_size_bytes() / _array_format->get_stride();
GeomVertexArrayDataPipelineReader reader(this, Thread::get_current_pipeline_stage());
return reader.get_num_rows();
}
////////////////////////////////////////////////////////////////////
// Function: GeomVertexArrayData::set_num_rows
// Access: Published
// Description: Sets the length of the array to n rows.
// Normally, you would not call this directly, since all
// of the arrays in a particular GeomVertexData must
// have the same number of rows; instead, call
// GeomVertexData::set_num_rows().
//
// The return value is true if the number of rows
// was changed, false if the object already contained n
// rows (or if there was some error).
//
// The new vertex data is initialized to 0, including
// the "color" column (but see
// GeomVertexData::set_num_rows()).
//
// Don't call this in a downstream thread unless you
// don't mind it blowing away other changes you might
// have recently made in an upstream thread.
////////////////////////////////////////////////////////////////////
INLINE bool GeomVertexArrayData::
set_num_rows(int n) {
GeomVertexArrayDataPipelineWriter writer(this, Thread::get_current_pipeline_stage(), true);
return writer.set_num_rows(n);
}
////////////////////////////////////////////////////////////////////
@@ -113,6 +141,39 @@ get_data() const {
return cdata->_data;
}
////////////////////////////////////////////////////////////////////
// Function: GeomVertexArrayData::modify_data
// Access: Published
// Description: Returns a modifiable pointer to the actual vertex
// array, so that application code may directly
// manipulate it. Use with caution.
//
// Don't call this in a downstream thread unless you
// don't mind it blowing away other changes you might
// have recently made in an upstream thread.
////////////////////////////////////////////////////////////////////
INLINE PTA_uchar GeomVertexArrayData::
modify_data() {
GeomVertexArrayDataPipelineWriter writer(this, Thread::get_current_pipeline_stage(), true);
return writer.modify_data();
}
////////////////////////////////////////////////////////////////////
// Function: GeomVertexArrayData::set_data
// Access: Published
// Description: Replaces the vertex data array with a completely new
// array.
//
// Don't call this in a downstream thread unless you
// don't mind it blowing away other changes you might
// have recently made in an upstream thread.
////////////////////////////////////////////////////////////////////
INLINE void GeomVertexArrayData::
set_data(CPTA_uchar array) {
GeomVertexArrayDataPipelineWriter writer(this, Thread::get_current_pipeline_stage(), true);
writer.set_data(array);
}
////////////////////////////////////////////////////////////////////
// Function: GeomVertexArrayData::CData::Constructor
// Access: Public
@@ -137,6 +198,222 @@ CData(const GeomVertexArrayData::CData &copy) :
{
}
////////////////////////////////////////////////////////////////////
// Function: GeomVertexArrayDataPipelineBase::Constructor
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
INLINE GeomVertexArrayDataPipelineBase::
GeomVertexArrayDataPipelineBase(GeomVertexArrayData *object,
int pipeline_stage,
GeomVertexArrayData::CData *cdata) :
_object(object),
_pipeline_stage(pipeline_stage),
_cdata(cdata)
{
}
////////////////////////////////////////////////////////////////////
// Function: GeomVertexArrayDataPipelineBase::get_pipeline_stage
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
INLINE int GeomVertexArrayDataPipelineBase::
get_pipeline_stage() const {
return _pipeline_stage;
}
////////////////////////////////////////////////////////////////////
// Function: GeomVertexArrayDataPipelineBase::get_array_format
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
INLINE const GeomVertexArrayFormat *GeomVertexArrayDataPipelineBase::
get_array_format() const {
return _object->_array_format;
}
////////////////////////////////////////////////////////////////////
// Function: GeomVertexArrayDataPipelineBase::get_usage_hint
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
INLINE GeomVertexArrayDataPipelineBase::UsageHint GeomVertexArrayDataPipelineBase::
get_usage_hint() const {
return _cdata->_usage_hint;
}
////////////////////////////////////////////////////////////////////
// Function: GeomVertexArrayDataPipelineBase::get_data
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
INLINE CPTA_uchar GeomVertexArrayDataPipelineBase::
get_data() const {
return _cdata->_data;
}
////////////////////////////////////////////////////////////////////
// Function: GeomVertexArrayDataPipelineBase::get_num_rows
// Access: Published
// Description:
////////////////////////////////////////////////////////////////////
INLINE int GeomVertexArrayDataPipelineBase::
get_num_rows() const {
return get_data_size_bytes() / _object->_array_format->get_stride();
}
////////////////////////////////////////////////////////////////////
// Function: GeomVertexArrayDataPipelineBase::get_data_size_bytes
// Access: Published
// Description:
////////////////////////////////////////////////////////////////////
INLINE int GeomVertexArrayDataPipelineBase::
get_data_size_bytes() const {
return _cdata->_data.size();
}
////////////////////////////////////////////////////////////////////
// Function: GeomVertexArrayDataPipelineBase::get_modified
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
INLINE UpdateSeq GeomVertexArrayDataPipelineBase::
get_modified() const {
return _cdata->_modified;
}
////////////////////////////////////////////////////////////////////
// Function: GeomVertexArrayDataPipelineReader::Constructor
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
INLINE GeomVertexArrayDataPipelineReader::
GeomVertexArrayDataPipelineReader(const GeomVertexArrayData *object,
int pipeline_stage) :
GeomVertexArrayDataPipelineBase((GeomVertexArrayData *)object,
pipeline_stage,
(GeomVertexArrayData::CData *)object->_cycler.read_stage(pipeline_stage))
{
nassertv(_object->test_ref_count_nonzero());
#ifdef DO_PIPELINING
nassertv(_cdata->test_ref_count_nonzero());
#endif // DO_PIPELINING
}
////////////////////////////////////////////////////////////////////
// Function: GeomVertexArrayDataPipelineReader::Copy Constructor
// Access: Private
// Description: Don't attempt to copy these objects.
////////////////////////////////////////////////////////////////////
INLINE GeomVertexArrayDataPipelineReader::
GeomVertexArrayDataPipelineReader(const GeomVertexArrayDataPipelineReader &copy) :
GeomVertexArrayDataPipelineBase(copy)
{
nassertv(false);
}
////////////////////////////////////////////////////////////////////
// Function: GeomVertexArrayDataPipelineReader::Copy Assignment Operator
// Access: Private
// Description: Don't attempt to copy these objects.
////////////////////////////////////////////////////////////////////
INLINE void GeomVertexArrayDataPipelineReader::
operator = (const GeomVertexArrayDataPipelineReader &) {
nassertv(false);
}
////////////////////////////////////////////////////////////////////
// Function: GeomVertexArrayDataPipelineReader::Destructor
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
INLINE GeomVertexArrayDataPipelineReader::
~GeomVertexArrayDataPipelineReader() {
nassertv(_object->test_ref_count_nonzero());
#ifdef DO_PIPELINING
nassertv(_cdata->test_ref_count_nonzero());
#endif // DO_PIPELINING
_object->_cycler.release_read_stage(_pipeline_stage, _cdata);
_object = NULL;
_cdata = NULL;
}
////////////////////////////////////////////////////////////////////
// Function: GeomVertexArrayDataPipelineReader::get_object
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
INLINE const GeomVertexArrayData *GeomVertexArrayDataPipelineReader::
get_object() const {
return _object;
}
////////////////////////////////////////////////////////////////////
// Function: GeomVertexArrayDataPipelineWriter::Constructor
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
INLINE GeomVertexArrayDataPipelineWriter::
GeomVertexArrayDataPipelineWriter(GeomVertexArrayData *object,
int pipeline_stage, bool force_to_0) :
GeomVertexArrayDataPipelineBase(object, pipeline_stage,
object->_cycler.write_stage_upstream(pipeline_stage, force_to_0))
{
nassertv(_object->test_ref_count_nonzero());
#ifdef DO_PIPELINING
nassertv(_cdata->test_ref_count_nonzero());
#endif // DO_PIPELINING
}
////////////////////////////////////////////////////////////////////
// Function: GeomVertexArrayDataPipelineWriter::Copy Constructor
// Access: Private
// Description: Don't attempt to copy these objects.
////////////////////////////////////////////////////////////////////
INLINE GeomVertexArrayDataPipelineWriter::
GeomVertexArrayDataPipelineWriter(const GeomVertexArrayDataPipelineWriter &copy) :
GeomVertexArrayDataPipelineBase(copy)
{
nassertv(false);
}
////////////////////////////////////////////////////////////////////
// Function: GeomVertexArrayDataPipelineWriter::Copy Assignment Operator
// Access: Private
// Description: Don't attempt to copy these objects.
////////////////////////////////////////////////////////////////////
INLINE void GeomVertexArrayDataPipelineWriter::
operator = (const GeomVertexArrayDataPipelineWriter &) {
nassertv(false);
}
////////////////////////////////////////////////////////////////////
// Function: GeomVertexArrayDataPipelineWriter::Destructor
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
INLINE GeomVertexArrayDataPipelineWriter::
~GeomVertexArrayDataPipelineWriter() {
nassertv(_object->test_ref_count_nonzero());
#ifdef DO_PIPELINING
nassertv(_cdata->test_ref_count_nonzero());
#endif // DO_PIPELINING
_object->_cycler.release_write_stage(_pipeline_stage, _cdata);
_object = NULL;
_cdata = NULL;
}
////////////////////////////////////////////////////////////////////
// Function: GeomVertexArrayDataPipelineWriter::get_object
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
INLINE GeomVertexArrayData *GeomVertexArrayDataPipelineWriter::
get_object() const {
return _object;
}
INLINE ostream &
operator << (ostream &out, const GeomVertexArrayData &obj) {
obj.output(out);
+72 -105
View File
@@ -105,66 +105,6 @@ GeomVertexArrayData::
release_all();
}
////////////////////////////////////////////////////////////////////
// Function: GeomVertexArrayData::set_num_rows
// Access: Published
// Description: Sets the length of the array to n rows.
// Normally, you would not call this directly, since all
// of the arrays in a particular GeomVertexData must
// have the same number of rows; instead, call
// GeomVertexData::set_num_rows().
//
// The return value is true if the number of rows
// was changed, false if the object already contained n
// rows (or if there was some error).
//
// The new vertex data is initialized to 0, including
// the "color" column (but see
// GeomVertexData::set_num_rows()).
//
// Don't call this in a downstream thread unless you
// don't mind it blowing away other changes you might
// have recently made in an upstream thread.
////////////////////////////////////////////////////////////////////
bool GeomVertexArrayData::
set_num_rows(int n) {
CDWriter cdata(_cycler, true);
int stride = _array_format->get_stride();
int delta = n - (cdata->_data.size() / stride);
if (delta != 0) {
if (cdata->_data.get_ref_count() > 1) {
// Copy-on-write: the data is already reffed somewhere else,
// so we're just going to make a copy.
PTA_uchar new_data;
new_data.reserve(n * stride);
new_data.insert(new_data.end(), n * stride, 0);
memcpy(new_data, cdata->_data,
min((size_t)(n * stride), cdata->_data.size()));
cdata->_data = new_data;
} else {
// We've got the only reference to the data, so we can change
// it directly.
if (delta > 0) {
cdata->_data.insert(cdata->_data.end(), delta * stride, 0);
} else {
cdata->_data.erase(cdata->_data.begin() + n * stride,
cdata->_data.end());
}
}
cdata->_modified = Geom::get_next_modified();
return true;
}
return false;
}
////////////////////////////////////////////////////////////////////
// Function: GeomVertexArrayData::set_usage_hint
// Access: Published
@@ -202,51 +142,6 @@ write(ostream &out, int indent_level) const {
_array_format->write_with_data(out, indent_level, this);
}
////////////////////////////////////////////////////////////////////
// Function: GeomVertexArrayData::modify_data
// Access: Published
// Description: Returns a modifiable pointer to the actual vertex
// array, so that application code may directly
// manipulate it. Use with caution.
//
// Don't call this in a downstream thread unless you
// don't mind it blowing away other changes you might
// have recently made in an upstream thread.
////////////////////////////////////////////////////////////////////
PTA_uchar GeomVertexArrayData::
modify_data() {
// Perform copy-on-write: if the reference count on the vertex data
// is greater than 1, assume some other GeomVertexData has the same
// pointer, so make a copy of it first.
CDWriter cdata(_cycler, true);
if (cdata->_data.get_ref_count() > 1) {
PTA_uchar orig_data = cdata->_data;
cdata->_data = PTA_uchar();
cdata->_data.v() = orig_data.v();
}
cdata->_modified = Geom::get_next_modified();
return cdata->_data;
}
////////////////////////////////////////////////////////////////////
// Function: GeomVertexArrayData::set_data
// Access: Published
// Description: Replaces the vertex data array with a completely new
// array.
//
// Don't call this in a downstream thread unless you
// don't mind it blowing away other changes you might
// have recently made in an upstream thread.
////////////////////////////////////////////////////////////////////
void GeomVertexArrayData::
set_data(CPTA_uchar array) {
CDWriter cdata(_cycler, true);
cdata->_data = (PTA_uchar &)array;
cdata->_modified = Geom::get_next_modified();
}
////////////////////////////////////////////////////////////////////
// Function: GeomVertexArrayData::prepare
// Access: Public
@@ -613,3 +508,75 @@ fillin(DatagramIterator &scan, BamReader *manager, void *extra_data) {
_modified = Geom::get_next_modified();
}
////////////////////////////////////////////////////////////////////
// Function: GeomVertexArrayDataPipelineWriter::set_num_rows
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
bool GeomVertexArrayDataPipelineWriter::
set_num_rows(int n) {
int stride = _object->_array_format->get_stride();
int delta = n - (_cdata->_data.size() / stride);
if (delta != 0) {
if (_cdata->_data.get_ref_count() > 1) {
// Copy-on-write: the data is already reffed somewhere else,
// so we're just going to make a copy.
PTA_uchar new_data;
new_data.reserve(n * stride);
new_data.insert(new_data.end(), n * stride, 0);
memcpy(new_data, _cdata->_data,
min((size_t)(n * stride), _cdata->_data.size()));
_cdata->_data = new_data;
} else {
// We've got the only reference to the data, so we can change
// it directly.
if (delta > 0) {
_cdata->_data.insert(_cdata->_data.end(), delta * stride, 0);
} else {
_cdata->_data.erase(_cdata->_data.begin() + n * stride,
_cdata->_data.end());
}
}
_cdata->_modified = Geom::get_next_modified();
return true;
}
return false;
}
////////////////////////////////////////////////////////////////////
// Function: GeomVertexArrayDataPipelineWriter::modify_data
// Access: Published
// Description:
////////////////////////////////////////////////////////////////////
PTA_uchar GeomVertexArrayDataPipelineWriter::
modify_data() {
// Perform copy-on-write: if the reference count on the vertex data
// is greater than 1, assume some other GeomVertexData has the same
// pointer, so make a copy of it first.
if (_cdata->_data.get_ref_count() > 1) {
PTA_uchar orig_data = _cdata->_data;
_cdata->_data = PTA_uchar();
_cdata->_data.v() = orig_data.v();
}
_cdata->_modified = Geom::get_next_modified();
return _cdata->_data;
}
////////////////////////////////////////////////////////////////////
// Function: GeomVertexArrayDataPipelineWriter::set_data
// Access: Published
// Description:
////////////////////////////////////////////////////////////////////
void GeomVertexArrayDataPipelineWriter::
set_data(CPTA_uchar array) {
_cdata->_data = (PTA_uchar &)array;
_cdata->_modified = Geom::get_next_modified();
}
+79 -3
View File
@@ -76,7 +76,7 @@ PUBLISHED:
INLINE bool has_column(const InternalName *name) const;
INLINE int get_num_rows() const;
bool set_num_rows(int n);
INLINE bool set_num_rows(int n);
INLINE void clear_rows();
INLINE int get_data_size_bytes() const;
@@ -86,8 +86,8 @@ PUBLISHED:
void write(ostream &out, int indent_level = 0) const;
INLINE CPTA_uchar get_data() const;
PTA_uchar modify_data();
void set_data(CPTA_uchar data);
INLINE PTA_uchar modify_data();
INLINE void set_data(CPTA_uchar data);
public:
void prepare(PreparedGraphicsObjects *prepared_objects);
@@ -133,6 +133,8 @@ private:
UsageHint _usage_hint;
PTA_uchar _data;
UpdateSeq _modified;
friend class GeomVertexArrayData;
};
PipelineCycler<CData> _cycler;
@@ -174,6 +176,80 @@ private:
friend class GeomCacheManager;
friend class GeomVertexData;
friend class PreparedGraphicsObjects;
friend class GeomVertexArrayDataPipelineBase;
friend class GeomVertexArrayDataPipelineReader;
friend class GeomVertexArrayDataPipelineWriter;
};
////////////////////////////////////////////////////////////////////
// Class : GeomVertexArrayDataPipelineBase
// Description : The common code from
// GeomVertexArrayDataPipelineReader and
// GeomVertexArrayDataPipelineWriter.
////////////////////////////////////////////////////////////////////
class EXPCL_PANDA GeomVertexArrayDataPipelineBase : public GeomEnums {
protected:
INLINE GeomVertexArrayDataPipelineBase(GeomVertexArrayData *object,
int pipeline_stage,
GeomVertexArrayData::CData *cdata);
public:
INLINE int get_pipeline_stage() const;
INLINE const GeomVertexArrayFormat *get_array_format() const;
INLINE UsageHint get_usage_hint() const;
INLINE CPTA_uchar get_data() const;
INLINE int get_num_rows() const;
INLINE int get_data_size_bytes() const;
INLINE UpdateSeq get_modified() const;
protected:
GeomVertexArrayData *_object;
int _pipeline_stage;
GeomVertexArrayData::CData *_cdata;
};
////////////////////////////////////////////////////////////////////
// Class : GeomVertexArrayDataPipelineReader
// Description : Encapsulates the data from a GeomVertexArrayData,
// pre-fetched for one stage of the pipeline.
////////////////////////////////////////////////////////////////////
class EXPCL_PANDA GeomVertexArrayDataPipelineReader : public GeomVertexArrayDataPipelineBase {
public:
INLINE GeomVertexArrayDataPipelineReader(const GeomVertexArrayData *object, int pipeline_stage);
private:
INLINE GeomVertexArrayDataPipelineReader(const GeomVertexArrayDataPipelineReader &copy);
INLINE void operator = (const GeomVertexArrayDataPipelineReader &copy);
public:
INLINE ~GeomVertexArrayDataPipelineReader();
ALLOC_DELETED_CHAIN(GeomVertexArrayDataPipelineReader);
INLINE const GeomVertexArrayData *get_object() const;
};
////////////////////////////////////////////////////////////////////
// Class : GeomVertexArrayDataPipelineWriter
// Description : Encapsulates the data from a GeomVertexArrayData,
// pre-fetched for one stage of the pipeline.
////////////////////////////////////////////////////////////////////
class EXPCL_PANDA GeomVertexArrayDataPipelineWriter : public GeomVertexArrayDataPipelineBase {
public:
INLINE GeomVertexArrayDataPipelineWriter(GeomVertexArrayData *object, int pipeline_stage, bool force_to_0);
private:
INLINE GeomVertexArrayDataPipelineWriter(const GeomVertexArrayDataPipelineWriter &copy);
INLINE void operator = (const GeomVertexArrayDataPipelineWriter &copy);
public:
INLINE ~GeomVertexArrayDataPipelineWriter();
ALLOC_DELETED_CHAIN(GeomVertexArrayDataPipelineWriter);
bool set_num_rows(int n);
INLINE GeomVertexArrayData *get_object() const;
PTA_uchar modify_data();
void set_data(CPTA_uchar data);
};
INLINE ostream &operator << (ostream &out, const GeomVertexArrayData &obj);
+412 -65
View File
@@ -29,17 +29,6 @@ get_name() const {
return _name;
}
////////////////////////////////////////////////////////////////////
// Function: GeomVertexData::get_format
// Access: Published
// Description: Returns a pointer to the GeomVertexFormat structure
// that defines this data.
////////////////////////////////////////////////////////////////////
INLINE const GeomVertexFormat *GeomVertexData::
get_format() const {
return _format;
}
////////////////////////////////////////////////////////////////////
// Function: GeomVertexData::get_usage_hint
// Access: Published
@@ -60,6 +49,18 @@ get_usage_hint() const {
return cdata->_usage_hint;
}
////////////////////////////////////////////////////////////////////
// Function: GeomVertexData::get_format
// Access: Published
// Description: Returns a pointer to the GeomVertexFormat structure
// that defines this data.
////////////////////////////////////////////////////////////////////
INLINE const GeomVertexFormat *GeomVertexData::
get_format() const {
CDReader cdata(_cycler);
return cdata->_format;
}
////////////////////////////////////////////////////////////////////
// Function: GeomVertexData::has_column
// Access: Published
@@ -69,7 +70,22 @@ get_usage_hint() const {
////////////////////////////////////////////////////////////////////
INLINE bool GeomVertexData::
has_column(const InternalName *name) const {
return _format->has_column(name);
CDReader cdata(_cycler);
return cdata->_format->has_column(name);
}
////////////////////////////////////////////////////////////////////
// Function: GeomVertexData::get_num_rows
// Access: Published
// Description: Returns the number of rows stored within all the
// arrays. All arrays store data for the same n
// rows.
////////////////////////////////////////////////////////////////////
INLINE int GeomVertexData::
get_num_rows() const {
GeomVertexDataPipelineReader reader(this, Thread::get_current_pipeline_stage());
reader.check_array_readers();
return reader.get_num_rows();
}
////////////////////////////////////////////////////////////////////
@@ -99,8 +115,9 @@ has_column(const InternalName *name) const {
////////////////////////////////////////////////////////////////////
INLINE bool GeomVertexData::
set_num_rows(int n) {
CDWriter cdata(_cycler, true);
return do_set_num_rows(n, cdata);
GeomVertexDataPipelineWriter writer(this, Thread::get_current_pipeline_stage(), true);
writer.check_array_writers();
return writer.set_num_rows(n);
}
////////////////////////////////////////////////////////////////////
@@ -130,6 +147,26 @@ get_array(int i) const {
return cdata->_arrays[i];
}
////////////////////////////////////////////////////////////////////
// Function: GeomVertexData::modify_array
// Access: Published
// Description: Returns a modifiable pointer to the indicated vertex
// array, so that application code may directly
// manipulate the data. You should avoid changing
// the length of this array, since all of the arrays
// should be kept in sync--use set_num_rows()
// instead.
//
// Don't call this in a downstream thread unless you
// don't mind it blowing away other changes you might
// have recently made in an upstream thread.
////////////////////////////////////////////////////////////////////
INLINE GeomVertexArrayData *GeomVertexData::
modify_array(int i) {
GeomVertexDataPipelineWriter writer(this, Thread::get_current_pipeline_stage(), true);
return writer.modify_array(i);
}
////////////////////////////////////////////////////////////////////
// Function: GeomVertexData::get_transform_table
// Access: Published
@@ -225,6 +262,18 @@ clear_slider_table() {
set_slider_table(NULL);
}
////////////////////////////////////////////////////////////////////
// Function: GeomVertexData::get_num_bytes
// Access: Published
// Description: Returns the total number of bytes consumed by the
// different arrays of the vertex data.
////////////////////////////////////////////////////////////////////
INLINE int GeomVertexData::
get_num_bytes() const {
GeomVertexDataPipelineReader reader(this, Thread::get_current_pipeline_stage());
return reader.get_num_bytes();
}
////////////////////////////////////////////////////////////////////
// Function: GeomVertexData::get_modified
// Access: Published
@@ -238,57 +287,6 @@ get_modified() const {
return cdata->_modified;
}
////////////////////////////////////////////////////////////////////
// Function: GeomVertexData::has_vertex
// Access: Public
// Description: Returns true if the data has a "vertex" column, false
// otherwise.
////////////////////////////////////////////////////////////////////
INLINE bool GeomVertexData::
has_vertex() const {
return (_format->get_vertex_column() != (GeomVertexColumn *)NULL);
}
////////////////////////////////////////////////////////////////////
// Function: GeomVertexData::is_vertex_transformed
// Access: Public
// Description: Returns true if the data has a "vertex" column and it
// is indicated as having been transformed into clip
// coordinates, false if there is no vertex column or if
// it contains ordinary 3-d pre-transformation points.
////////////////////////////////////////////////////////////////////
INLINE bool GeomVertexData::
is_vertex_transformed() const {
const GeomVertexColumn *column = _format->get_vertex_column();
if (column != (GeomVertexColumn *)NULL) {
return column->get_contents() == C_clip_point;
}
return false;
}
////////////////////////////////////////////////////////////////////
// Function: GeomVertexData::has_normal
// Access: Public
// Description: Returns true if the data has a "normal" column, false
// otherwise.
////////////////////////////////////////////////////////////////////
INLINE bool GeomVertexData::
has_normal() const {
return (_format->get_normal_column() != (GeomVertexColumn *)NULL);
}
////////////////////////////////////////////////////////////////////
// Function: GeomVertexData::has_color
// Access: Public
// Description: Returns true if the data has a "color" column, false
// otherwise.
////////////////////////////////////////////////////////////////////
INLINE bool GeomVertexData::
has_color() const {
return (_format->get_color_column() != (GeomVertexColumn *)NULL);
}
////////////////////////////////////////////////////////////////////
// Function: GeomVertexData::pack_abcd
// Access: Public, Static
@@ -448,6 +446,7 @@ CData() :
INLINE GeomVertexData::CData::
CData(const GeomVertexData::CData &copy) :
_usage_hint(copy._usage_hint),
_format(copy._format),
_arrays(copy._arrays),
_transform_table(copy._transform_table),
_transform_blend_table(copy._transform_blend_table),
@@ -458,6 +457,354 @@ CData(const GeomVertexData::CData &copy) :
{
}
////////////////////////////////////////////////////////////////////
// Function: GeomVertexDataPipelineBase::Constructor
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
INLINE GeomVertexDataPipelineBase::
GeomVertexDataPipelineBase(GeomVertexData *object,
int pipeline_stage,
GeomVertexData::CData *cdata) :
_object(object),
_pipeline_stage(pipeline_stage),
_cdata(cdata)
{
}
////////////////////////////////////////////////////////////////////
// Function: GeomVertexDataPipelineBase::get_pipeline_stage
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
INLINE int GeomVertexDataPipelineBase::
get_pipeline_stage() const {
return _pipeline_stage;
}
////////////////////////////////////////////////////////////////////
// Function: GeomVertexDataPipelineBase::get_usage_hint
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
INLINE GeomVertexDataPipelineBase::UsageHint GeomVertexDataPipelineBase::
get_usage_hint() const {
return _cdata->_usage_hint;
}
////////////////////////////////////////////////////////////////////
// Function: GeomVertexDataPipelineBase::get_format
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
INLINE const GeomVertexFormat *GeomVertexDataPipelineBase::
get_format() const {
return _cdata->_format;
}
////////////////////////////////////////////////////////////////////
// Function: GeomVertexDataPipelineBase::has_column
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
INLINE bool GeomVertexDataPipelineBase::
has_column(const InternalName *name) const {
return _cdata->_format->has_column(name);
}
////////////////////////////////////////////////////////////////////
// Function: GeomVertexDataPipelineBase::get_num_arrays
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
INLINE int GeomVertexDataPipelineBase::
get_num_arrays() const {
return _cdata->_arrays.size();
}
////////////////////////////////////////////////////////////////////
// Function: GeomVertexDataPipelineBase::get_array
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
INLINE const GeomVertexArrayData *GeomVertexDataPipelineBase::
get_array(int i) const {
nassertr(i >= 0 && i < (int)_cdata->_arrays.size(), NULL);
return _cdata->_arrays[i];
}
////////////////////////////////////////////////////////////////////
// Function: GeomVertexDataPipelineBase::get_transform_table
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
INLINE const TransformTable *GeomVertexDataPipelineBase::
get_transform_table() const {
return _cdata->_transform_table;
}
////////////////////////////////////////////////////////////////////
// Function: GeomVertexDataPipelineBase::get_transform_blend_table
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
INLINE const TransformBlendTable *GeomVertexDataPipelineBase::
get_transform_blend_table() const {
return _cdata->_transform_blend_table;
}
////////////////////////////////////////////////////////////////////
// Function: GeomVertexDataPipelineBase::get_slider_table
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
INLINE const SliderTable *GeomVertexDataPipelineBase::
get_slider_table() const {
return _cdata->_slider_table;
}
////////////////////////////////////////////////////////////////////
// Function: GeomVertexDataPipelineBase::get_modified
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
INLINE UpdateSeq GeomVertexDataPipelineBase::
get_modified() const {
return _cdata->_modified;
}
////////////////////////////////////////////////////////////////////
// Function: GeomVertexDataPipelineReader::Constructor
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
INLINE GeomVertexDataPipelineReader::
GeomVertexDataPipelineReader(const GeomVertexData *object,
int pipeline_stage) :
GeomVertexDataPipelineBase((GeomVertexData *)object, pipeline_stage,
(GeomVertexData::CData *)object->_cycler.read_stage(pipeline_stage)),
_got_array_readers(false)
{
nassertv(_object->test_ref_count_nonzero());
#ifdef DO_PIPELINING
nassertv(_cdata->test_ref_count_nonzero());
#endif // DO_PIPELINING
}
////////////////////////////////////////////////////////////////////
// Function: GeomVertexDataPipelineReader::Copy Constructor
// Access: Private
// Description: Don't attempt to copy these objects.
////////////////////////////////////////////////////////////////////
INLINE GeomVertexDataPipelineReader::
GeomVertexDataPipelineReader(const GeomVertexDataPipelineReader &copy) :
GeomVertexDataPipelineBase(copy)
{
nassertv(false);
}
////////////////////////////////////////////////////////////////////
// Function: GeomVertexDataPipelineReader::Copy Assignment Operator
// Access: Private
// Description: Don't attempt to copy these objects.
////////////////////////////////////////////////////////////////////
INLINE void GeomVertexDataPipelineReader::
operator = (const GeomVertexDataPipelineReader &) {
nassertv(false);
}
////////////////////////////////////////////////////////////////////
// Function: GeomVertexDataPipelineReader::Destructor
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
INLINE GeomVertexDataPipelineReader::
~GeomVertexDataPipelineReader() {
if (_got_array_readers) {
delete_array_readers();
}
nassertv(_object->test_ref_count_nonzero());
#ifdef DO_PIPELINING
nassertv(_cdata->test_ref_count_nonzero());
#endif // DO_PIPELINING
_object->_cycler.release_read_stage(_pipeline_stage, _cdata);
_object = NULL;
_cdata = NULL;
}
////////////////////////////////////////////////////////////////////
// Function: GeomVertexDataPipelineReader::get_object
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
INLINE const GeomVertexData *GeomVertexDataPipelineReader::
get_object() const {
return _object;
}
////////////////////////////////////////////////////////////////////
// Function: GeomVertexDataPipelineReader::check_array_readers
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
INLINE void GeomVertexDataPipelineReader::
check_array_readers() const {
if (!_got_array_readers) {
((GeomVertexDataPipelineReader *)this)->make_array_readers();
}
}
////////////////////////////////////////////////////////////////////
// Function: GeomVertexDataPipelineReader::get_array_reader
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
INLINE const GeomVertexArrayDataPipelineReader *GeomVertexDataPipelineReader::
get_array_reader(int i) const {
nassertr(_got_array_readers, NULL);
nassertr(i >= 0 && i < (int)_array_readers.size(), NULL);
return _array_readers[i];
}
////////////////////////////////////////////////////////////////////
// Function: GeomVertexDataPipelineReader::has_vertex
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
INLINE bool GeomVertexDataPipelineReader::
has_vertex() const {
return (_cdata->_format->get_vertex_column() != (GeomVertexColumn *)NULL);
}
////////////////////////////////////////////////////////////////////
// Function: GeomVertexDataPipelineReader::is_vertex_transformed
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
INLINE bool GeomVertexDataPipelineReader::
is_vertex_transformed() const {
const GeomVertexColumn *column = _cdata->_format->get_vertex_column();
if (column != (GeomVertexColumn *)NULL) {
return column->get_contents() == C_clip_point;
}
return false;
}
////////////////////////////////////////////////////////////////////
// Function: GeomVertexDataPipelineReader::has_normal
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
INLINE bool GeomVertexDataPipelineReader::
has_normal() const {
return (_cdata->_format->get_normal_column() != (GeomVertexColumn *)NULL);
}
////////////////////////////////////////////////////////////////////
// Function: GeomVertexDataPipelineReader::has_color
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
INLINE bool GeomVertexDataPipelineReader::
has_color() const {
return (_cdata->_format->get_color_column() != (GeomVertexColumn *)NULL);
}
////////////////////////////////////////////////////////////////////
// Function: GeomVertexDataPipelineWriter::Constructor
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
INLINE GeomVertexDataPipelineWriter::
GeomVertexDataPipelineWriter(GeomVertexData *object,
int pipeline_stage, bool force_to_0) :
GeomVertexDataPipelineBase(object, pipeline_stage,
object->_cycler.write_stage_upstream(pipeline_stage, force_to_0)),
_force_to_0(force_to_0),
_got_array_writers(false)
{
nassertv(_object->test_ref_count_nonzero());
#ifdef DO_PIPELINING
nassertv(_cdata->test_ref_count_nonzero());
#endif // DO_PIPELINING
}
////////////////////////////////////////////////////////////////////
// Function: GeomVertexDataPipelineWriter::Copy Constructor
// Access: Private
// Description: Don't attempt to copy these objects.
////////////////////////////////////////////////////////////////////
INLINE GeomVertexDataPipelineWriter::
GeomVertexDataPipelineWriter(const GeomVertexDataPipelineWriter &copy) :
GeomVertexDataPipelineBase(copy)
{
nassertv(false);
}
////////////////////////////////////////////////////////////////////
// Function: GeomVertexDataPipelineWriter::Copy Assignment Operator
// Access: Private
// Description: Don't attempt to copy these objects.
////////////////////////////////////////////////////////////////////
INLINE void GeomVertexDataPipelineWriter::
operator = (const GeomVertexDataPipelineWriter &) {
nassertv(false);
}
////////////////////////////////////////////////////////////////////
// Function: GeomVertexDataPipelineWriter::Destructor
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
INLINE GeomVertexDataPipelineWriter::
~GeomVertexDataPipelineWriter() {
if (_got_array_writers) {
delete_array_writers();
}
nassertv(_object->test_ref_count_nonzero());
#ifdef DO_PIPELINING
nassertv(_cdata->test_ref_count_nonzero());
#endif // DO_PIPELINING
_object->_cycler.release_write_stage(_pipeline_stage, _cdata);
_object = NULL;
_cdata = NULL;
}
////////////////////////////////////////////////////////////////////
// Function: GeomVertexDataPipelineWriter::get_object
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
INLINE GeomVertexData *GeomVertexDataPipelineWriter::
get_object() const {
return _object;
}
////////////////////////////////////////////////////////////////////
// Function: GeomVertexDataPipelineWriter::check_array_writers
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
INLINE void GeomVertexDataPipelineWriter::
check_array_writers() const {
if (!_got_array_writers) {
((GeomVertexDataPipelineWriter *)this)->make_array_writers();
}
}
////////////////////////////////////////////////////////////////////
// Function: GeomVertexDataPipelineWriter::get_array_writer
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
INLINE GeomVertexArrayDataPipelineWriter *GeomVertexDataPipelineWriter::
get_array_writer(int i) const {
nassertr(_got_array_writers, NULL);
nassertr(i >= 0 && i < (int)_array_writers.size(), NULL);
return _array_writers[i];
}
INLINE ostream &
operator << (ostream &out, const GeomVertexData &obj) {
obj.output(out);
File diff suppressed because it is too large Load Diff
+134 -30
View File
@@ -91,22 +91,22 @@ PUBLISHED:
INLINE const string &get_name() const;
void set_name(const string &name);
INLINE const GeomVertexFormat *get_format() const;
void set_format(const GeomVertexFormat *format);
INLINE UsageHint get_usage_hint() const;
void set_usage_hint(UsageHint usage_hint);
INLINE const GeomVertexFormat *get_format() const;
void set_format(const GeomVertexFormat *format);
INLINE bool has_column(const InternalName *name) const;
int get_num_rows() const;
INLINE int get_num_rows() const;
INLINE bool set_num_rows(int n);
void clear_rows();
INLINE int get_num_arrays() const;
INLINE const GeomVertexArrayData *get_array(int i) const;
GeomVertexArrayData *modify_array(int i);
void set_array(int i, const GeomVertexArrayData *array);
INLINE GeomVertexArrayData *modify_array(int i);
INLINE void set_array(int i, const GeomVertexArrayData *array);
INLINE const TransformTable *get_transform_table() const;
void set_transform_table(const TransformTable *table);
@@ -121,7 +121,7 @@ PUBLISHED:
void set_slider_table(const SliderTable *table);
INLINE void clear_slider_table();
int get_num_bytes() const;
INLINE int get_num_bytes() const;
INLINE UpdateSeq get_modified() const;
void copy_from(const GeomVertexData *source, bool keep_data_objects);
@@ -152,27 +152,6 @@ PUBLISHED:
void clear_cache_stage();
public:
bool get_array_info(const InternalName *name,
const GeomVertexArrayData *&array_data,
int &num_values, NumericType &numeric_type,
int &start, int &stride) const;
INLINE bool has_vertex() const;
INLINE bool is_vertex_transformed() const;
bool get_vertex_info(const GeomVertexArrayData *&array_data,
int &num_values, NumericType &numeric_type,
int &start, int &stride) const;
INLINE bool has_normal() const;
bool get_normal_info(const GeomVertexArrayData *&array_data,
NumericType &numeric_type,
int &start, int &stride) const;
INLINE bool has_color() const;
bool get_color_info(const GeomVertexArrayData *&array_data,
int &num_values, NumericType &numeric_type,
int &start, int &stride) const;
static INLINE PN_uint32 pack_abcd(unsigned int a, unsigned int b,
unsigned int c, unsigned int d);
static INLINE unsigned int unpack_abcd_a(PN_uint32 data);
@@ -201,7 +180,6 @@ private:
private:
string _name;
CPT(GeomVertexFormat) _format;
typedef pvector< PT(GeomVertexArrayData) > Arrays;
@@ -256,6 +234,7 @@ private:
}
UsageHint _usage_hint;
CPT(GeomVertexFormat) _format;
Arrays _arrays;
CPT(TransformTable) _transform_table;
PT(TransformBlendTable) _transform_blend_table;
@@ -274,7 +253,6 @@ private:
Cache _cache;
private:
bool do_set_num_rows(int n, CData *cdata);
void update_animated_vertices(CData *cdata);
static PStatCollector _convert_pcollector;
@@ -315,6 +293,132 @@ private:
static TypeHandle _type_handle;
friend class CacheEntry;
friend class GeomVertexDataPipelineBase;
friend class GeomVertexDataPipelineReader;
friend class GeomVertexDataPipelineWriter;
};
////////////////////////////////////////////////////////////////////
// Class : GeomVertexDataPipelineBase
// Description : The common code from
// GeomVertexDataPipelineReader and
// GeomVertexDataPipelineWriter.
////////////////////////////////////////////////////////////////////
class EXPCL_PANDA GeomVertexDataPipelineBase : public GeomEnums {
protected:
INLINE GeomVertexDataPipelineBase(GeomVertexData *object,
int pipeline_stage,
GeomVertexData::CData *cdata);
public:
INLINE int get_pipeline_stage() const;
INLINE const GeomVertexFormat *get_format() const;
INLINE bool has_column(const InternalName *name) const;
INLINE UsageHint get_usage_hint() const;
INLINE int get_num_arrays() const;
INLINE const GeomVertexArrayData *get_array(int i) const;
INLINE const TransformTable *get_transform_table() const;
INLINE const TransformBlendTable *get_transform_blend_table() const;
INLINE const SliderTable *get_slider_table() const;
int get_num_bytes() const;
INLINE UpdateSeq get_modified() const;
protected:
GeomVertexData *_object;
int _pipeline_stage;
GeomVertexData::CData *_cdata;
};
////////////////////////////////////////////////////////////////////
// Class : GeomVertexDataPipelineReader
// Description : Encapsulates the data from a GeomVertexData,
// pre-fetched for one stage of the pipeline.
////////////////////////////////////////////////////////////////////
class EXPCL_PANDA GeomVertexDataPipelineReader : public GeomVertexDataPipelineBase {
public:
INLINE GeomVertexDataPipelineReader(const GeomVertexData *object, int pipeline_stage);
private:
INLINE GeomVertexDataPipelineReader(const GeomVertexDataPipelineReader &copy);
INLINE void operator = (const GeomVertexDataPipelineReader &copy);
public:
INLINE ~GeomVertexDataPipelineReader();
ALLOC_DELETED_CHAIN(GeomVertexDataPipelineReader);
INLINE const GeomVertexData *get_object() const;
INLINE void check_array_readers() const;
INLINE const GeomVertexArrayDataPipelineReader *get_array_reader(int i) const;
int get_num_rows() const;
bool get_array_info(const InternalName *name,
const GeomVertexArrayDataPipelineReader *&array_reader,
int &num_values, NumericType &numeric_type,
int &start, int &stride) const;
INLINE bool has_vertex() const;
INLINE bool is_vertex_transformed() const;
bool get_vertex_info(const GeomVertexArrayDataPipelineReader *&array_reader,
int &num_values, NumericType &numeric_type,
int &start, int &stride) const;
INLINE bool has_normal() const;
bool get_normal_info(const GeomVertexArrayDataPipelineReader *&array_reader,
NumericType &numeric_type,
int &start, int &stride) const;
INLINE bool has_color() const;
bool get_color_info(const GeomVertexArrayDataPipelineReader *&array_reader,
int &num_values, NumericType &numeric_type,
int &start, int &stride) const;
private:
void make_array_readers();
void delete_array_readers();
bool _got_array_readers;
typedef pvector<GeomVertexArrayDataPipelineReader *> ArrayReaders;
ArrayReaders _array_readers;
};
////////////////////////////////////////////////////////////////////
// Class : GeomVertexDataPipelineWriter
// Description : Encapsulates the data from a GeomVertexData,
// pre-fetched for one stage of the pipeline.
////////////////////////////////////////////////////////////////////
class EXPCL_PANDA GeomVertexDataPipelineWriter : public GeomVertexDataPipelineBase {
public:
INLINE GeomVertexDataPipelineWriter(GeomVertexData *object, int pipeline_stage,
bool force_to_0);
private:
INLINE GeomVertexDataPipelineWriter(const GeomVertexDataPipelineWriter &copy);
INLINE void operator = (const GeomVertexDataPipelineWriter &copy);
public:
INLINE ~GeomVertexDataPipelineWriter();
ALLOC_DELETED_CHAIN(GeomVertexDataPipelineWriter);
INLINE GeomVertexData *get_object() const;
INLINE void check_array_writers() const;
INLINE GeomVertexArrayDataPipelineWriter *get_array_writer(int i) const;
GeomVertexArrayData *modify_array(int i);
void set_array(int i, const GeomVertexArrayData *array);
int get_num_rows() const;
bool set_num_rows(int n);
private:
void make_array_writers();
void delete_array_writers();
bool _force_to_0;
bool _got_array_writers;
typedef pvector<GeomVertexArrayDataPipelineWriter *> ArrayWriters;
ArrayWriters _array_writers;
};
INLINE ostream &operator << (ostream &out, const GeomVertexData &obj);
+86 -39
View File
@@ -27,7 +27,9 @@
////////////////////////////////////////////////////////////////////
INLINE GeomVertexReader::
GeomVertexReader() :
_vertex_data(NULL)
_data_reader(NULL),
_array_reader(NULL),
_owns_reader(false)
{
initialize();
}
@@ -40,7 +42,9 @@ GeomVertexReader() :
////////////////////////////////////////////////////////////////////
INLINE GeomVertexReader::
GeomVertexReader(const GeomVertexData *vertex_data) :
_vertex_data(vertex_data)
_data_reader(new GeomVertexDataPipelineReader(vertex_data, Thread::get_current_pipeline_stage())),
_array_reader(NULL),
_owns_reader(true)
{
initialize();
}
@@ -54,7 +58,9 @@ GeomVertexReader(const GeomVertexData *vertex_data) :
////////////////////////////////////////////////////////////////////
INLINE GeomVertexReader::
GeomVertexReader(const GeomVertexData *vertex_data, const string &name) :
_vertex_data(vertex_data)
_data_reader(new GeomVertexDataPipelineReader(vertex_data, Thread::get_current_pipeline_stage())),
_array_reader(NULL),
_owns_reader(true)
{
initialize();
set_column(name);
@@ -69,8 +75,10 @@ GeomVertexReader(const GeomVertexData *vertex_data, const string &name) :
////////////////////////////////////////////////////////////////////
INLINE GeomVertexReader::
GeomVertexReader(const GeomVertexData *vertex_data,
const InternalName *name) :
_vertex_data(vertex_data)
const InternalName *name) :
_data_reader(new GeomVertexDataPipelineReader(vertex_data, Thread::get_current_pipeline_stage())),
_array_reader(NULL),
_owns_reader(true)
{
initialize();
set_column(name);
@@ -84,7 +92,9 @@ GeomVertexReader(const GeomVertexData *vertex_data,
////////////////////////////////////////////////////////////////////
INLINE GeomVertexReader::
GeomVertexReader(const GeomVertexArrayData *array_data) :
_array_data(array_data)
_data_reader(NULL),
_array_reader(new GeomVertexArrayDataPipelineReader(array_data, Thread::get_current_pipeline_stage())),
_owns_reader(true)
{
initialize();
}
@@ -97,22 +107,44 @@ GeomVertexReader(const GeomVertexArrayData *array_data) :
////////////////////////////////////////////////////////////////////
INLINE GeomVertexReader::
GeomVertexReader(const GeomVertexArrayData *array_data, int column) :
_array_data(array_data)
_data_reader(NULL),
_array_reader(new GeomVertexArrayDataPipelineReader(array_data, Thread::get_current_pipeline_stage())),
_owns_reader(true)
{
initialize();
set_column(column);
}
////////////////////////////////////////////////////////////////////
// Function: GeomVertexReader::Constructor
// Access: Public
// Description: Constructs a new reader to process the vertices of
// the indicated data object. This flavor creates the
// reader specifically to process the named data type.
////////////////////////////////////////////////////////////////////
INLINE GeomVertexReader::
GeomVertexReader(const GeomVertexDataPipelineReader *data_reader,
const InternalName *name) :
_data_reader(data_reader),
_array_reader(NULL),
_owns_reader(false)
{
initialize();
set_column(name);
}
////////////////////////////////////////////////////////////////////
// Function: GeomVertexReader::Copy Constructor
// Access: Published
// Description:
// Description: The copy constructor steals ownership of the reader
// pointer.
////////////////////////////////////////////////////////////////////
INLINE GeomVertexReader::
GeomVertexReader(const GeomVertexReader &copy) :
_vertex_data(copy._vertex_data),
_data_reader(copy._data_reader),
_array(copy._array),
_array_data(copy._array_data),
_array_reader(copy._array_reader),
_owns_reader(copy._owns_reader),
_packer(copy._packer),
_stride(copy._stride),
_pointer_begin(copy._pointer_begin),
@@ -120,24 +152,33 @@ GeomVertexReader(const GeomVertexReader &copy) :
_pointer(copy._pointer),
_start_row(copy._start_row)
{
((GeomVertexReader &)copy)._owns_reader = false;
}
////////////////////////////////////////////////////////////////////
// Function: GeomVertexReader::Copy Assignment Operator
// Access: Published
// Description:
// Description: The copy constructor steals ownership of the reader
// pointer.
////////////////////////////////////////////////////////////////////
INLINE void GeomVertexReader::
operator = (const GeomVertexReader &copy) {
_vertex_data = copy._vertex_data;
if (_owns_reader) {
clear_reader();
}
_data_reader = copy._data_reader;
_array = copy._array;
_array_data = copy._array_data;
_array_reader = copy._array_reader;
_owns_reader = copy._owns_reader;
_packer = copy._packer;
_stride = copy._stride;
_pointer_begin = copy._pointer_begin;
_pointer_end = copy._pointer_end;
_pointer = copy._pointer;
_start_row = copy._start_row;
((GeomVertexReader &)copy)._owns_reader = false;
}
////////////////////////////////////////////////////////////////////
@@ -147,6 +188,9 @@ operator = (const GeomVertexReader &copy) {
////////////////////////////////////////////////////////////////////
INLINE GeomVertexReader::
~GeomVertexReader() {
if (_owns_reader) {
clear_reader();
}
}
////////////////////////////////////////////////////////////////////
@@ -158,7 +202,10 @@ INLINE GeomVertexReader::
////////////////////////////////////////////////////////////////////
INLINE const GeomVertexData *GeomVertexReader::
get_vertex_data() const {
return _vertex_data;
if (_data_reader != (GeomVertexDataPipelineReader *)NULL) {
return _data_reader->get_object();
}
return NULL;
}
////////////////////////////////////////////////////////////////////
@@ -169,7 +216,7 @@ get_vertex_data() const {
////////////////////////////////////////////////////////////////////
INLINE const GeomVertexArrayData *GeomVertexReader::
get_array_data() const {
return _array_data;
return _array_reader->get_object();
}
////////////////////////////////////////////////////////////////////
@@ -187,12 +234,12 @@ get_array_data() const {
////////////////////////////////////////////////////////////////////
INLINE bool GeomVertexReader::
set_column(int column) {
if (_vertex_data != (const GeomVertexData *)NULL) {
return set_column(_vertex_data->get_format()->get_array_with(column),
_vertex_data->get_format()->get_column(column));
if (_data_reader != (const GeomVertexDataPipelineReader *)NULL) {
return set_column(_data_reader->get_format()->get_array_with(column),
_data_reader->get_format()->get_column(column));
}
if (_array_data != (const GeomVertexArrayData *)NULL) {
return set_column(0, _array_data->get_array_format()->get_column(column));
if (_array_reader != (const GeomVertexArrayDataPipelineReader *)NULL) {
return set_column(0, _array_reader->get_array_format()->get_column(column));
}
return false;
}
@@ -230,12 +277,12 @@ set_column(const string &name) {
////////////////////////////////////////////////////////////////////
INLINE bool GeomVertexReader::
set_column(const InternalName *name) {
if (_vertex_data != (const GeomVertexData *)NULL) {
return set_column(_vertex_data->get_format()->get_array_with(name),
_vertex_data->get_format()->get_column(name));
if (_data_reader != (const GeomVertexDataPipelineReader *)NULL) {
return set_column(_data_reader->get_format()->get_array_with(name),
_data_reader->get_format()->get_column(name));
}
if (_array_data != (const GeomVertexArrayData *)NULL) {
return set_column(0, _array_data->get_array_format()->get_column(name));
if (_array_reader != (const GeomVertexArrayDataPipelineReader *)NULL) {
return set_column(0, _array_reader->get_array_format()->get_column(name));
}
return false;
@@ -454,14 +501,14 @@ get_packer() const {
////////////////////////////////////////////////////////////////////
INLINE void GeomVertexReader::
set_pointer(int row) {
if (_vertex_data != (const GeomVertexData *)NULL) {
const GeomVertexArrayData *array_data = _vertex_data->get_array(_array);
_pointer_begin = array_data->get_data();
_pointer_end = _pointer_begin + array_data->get_data_size_bytes();
if (_data_reader != (const GeomVertexDataPipelineReader *)NULL) {
const GeomVertexArrayDataPipelineReader *array_reader = _data_reader->get_array_reader(_array);
_pointer_begin = array_reader->get_data();
_pointer_end = _pointer_begin + array_reader->get_data_size_bytes();
} else {
_pointer_begin = _array_data->get_data();
_pointer_end = _pointer_begin + _array_data->get_data_size_bytes();
_pointer_begin = _array_reader->get_data();
_pointer_end = _pointer_begin + _array_reader->get_data_size_bytes();
}
quick_set_pointer(row);
}
@@ -478,11 +525,11 @@ quick_set_pointer(int row) {
nassertv(has_column());
#ifdef _DEBUG
if (_vertex_data != (const GeomVertexData *)NULL) {
const GeomVertexArrayData *array_data = _vertex_data->get_array(_array);
nassertv(_pointer_begin == array_data->get_data());
if (_data_reader != (const GeomVertexDataPipelineReader *)NULL) {
const GeomVertexArrayDataPipelineReader *array_reader = _data_reader->get_array_reader(_array);
nassertv(_pointer_begin == array_reader->get_data());
} else {
nassertv(_pointer_begin == _array_data->get_data());
nassertv(_pointer_begin == _array_reader->get_data());
}
#endif
@@ -499,11 +546,11 @@ INLINE const unsigned char *GeomVertexReader::
inc_pointer() {
#ifdef _DEBUG
nassertr(_pointer < _pointer_end, empty_buffer);
if (_vertex_data != (const GeomVertexData *)NULL){
const GeomVertexArrayData *array_data = _vertex_data->get_array(_array);
nassertr(_pointer >= array_data->get_data().p() && _pointer < array_data->get_data().p() + array_data->get_data_size_bytes(), empty_buffer);
if (_data_reader != (const GeomVertexDataPipelineReader *)NULL){
const GeomVertexArrayDataPipelineReader *array_reader = _data_reader->get_array_reader(_array);
nassertr(_pointer >= array_reader->get_data().p() && _pointer < array_reader->get_data().p() + array_reader->get_data_size_bytes(), empty_buffer);
} else {
nassertr(_pointer >= _array_data->get_data().p() && _pointer < _array_data->get_data().p() + _array_data->get_data_size_bytes(), empty_buffer);
nassertr(_pointer >= _array_reader->get_data().p() && _pointer < _array_reader->get_data().p() + _array_reader->get_data_size_bytes(), empty_buffer);
}
#endif
+33 -7
View File
@@ -40,8 +40,8 @@ const unsigned char GeomVertexReader::empty_buffer[100] = { 0 };
////////////////////////////////////////////////////////////////////
bool GeomVertexReader::
set_column(int array, const GeomVertexColumn *column) {
if (_vertex_data == (const GeomVertexData *)NULL &&
_array_data == (const GeomVertexArrayData *)NULL) {
if (_data_reader == (const GeomVertexDataPipelineReader *)NULL &&
_array_reader == (const GeomVertexArrayDataPipelineReader *)NULL) {
return false;
}
@@ -56,18 +56,18 @@ set_column(int array, const GeomVertexColumn *column) {
return false;
}
if (_vertex_data != (const GeomVertexData *)NULL) {
if (_data_reader != (const GeomVertexDataPipelineReader *)NULL) {
#ifndef NDEBUG
_array = -1;
_packer = NULL;
nassertr(array >= 0 && array < _vertex_data->get_num_arrays(), false);
nassertr(array >= 0 && array < _data_reader->get_num_arrays(), false);
#endif
_array = array;
const GeomVertexArrayData *array_data =_vertex_data->get_array(_array);
_stride = array_data->get_array_format()->get_stride();
const GeomVertexArrayDataPipelineReader *array_reader = _data_reader->get_array_reader(_array);
_stride = array_reader->get_array_format()->get_stride();
} else {
_stride = _array_data->get_array_format()->get_stride();
_stride = _array_reader->get_array_format()->get_stride();
}
_packer = column->_packer;
@@ -103,6 +103,10 @@ output(ostream &out) const {
////////////////////////////////////////////////////////////////////
void GeomVertexReader::
initialize() {
if (_data_reader != (const GeomVertexDataPipelineReader *)NULL) {
_data_reader->check_array_readers();
}
_array = 0;
_packer = NULL;
_pointer_begin = NULL;
@@ -110,3 +114,25 @@ initialize() {
_pointer = NULL;
_start_row = 0;
}
////////////////////////////////////////////////////////////////////
// Function: GeomVertexReader::clear_reader
// Access: Private
// Description: Destructs the GeomVertexDataPipelineReader, when
// necessary, for instance when this object destructs.
////////////////////////////////////////////////////////////////////
void GeomVertexReader::
clear_reader() {
nassertv(_owns_reader);
if (_data_reader != (const GeomVertexDataPipelineReader *)NULL) {
delete (GeomVertexDataPipelineReader *)_data_reader;
_data_reader = NULL;
} else {
nassertv(_array_reader != (const GeomVertexArrayDataPipelineReader *)NULL);
delete (GeomVertexArrayDataPipelineReader *)_array_reader;
_array_reader = NULL;
}
_owns_reader = false;
}
+10 -2
View File
@@ -68,6 +68,12 @@ PUBLISHED:
INLINE GeomVertexReader(const GeomVertexArrayData *array_data);
INLINE GeomVertexReader(const GeomVertexArrayData *array_data,
int column);
public:
INLINE GeomVertexReader(const GeomVertexDataPipelineReader *data_reader,
const InternalName *name);
PUBLISHED:
INLINE GeomVertexReader(const GeomVertexReader &copy);
INLINE void operator = (const GeomVertexReader &copy);
INLINE ~GeomVertexReader();
@@ -107,6 +113,7 @@ protected:
private:
void initialize();
void clear_reader();
INLINE void set_pointer(int row);
INLINE void quick_set_pointer(int row);
@@ -117,9 +124,10 @@ private:
// must not keep a pointer to the particular ArrayData we are
// working on (if we do, it may result in an extra copy of the data
// due to holding the reference count).
CPT(GeomVertexData) _vertex_data;
const GeomVertexDataPipelineReader *_data_reader;
int _array;
CPT(GeomVertexArrayData) _array_data;
const GeomVertexArrayDataPipelineReader *_array_reader;
bool _owns_reader;
GeomVertexColumn::Packer *_packer;
int _stride;
+83 -39
View File
@@ -27,7 +27,9 @@
////////////////////////////////////////////////////////////////////
INLINE GeomVertexWriter::
GeomVertexWriter() :
_vertex_data(NULL)
_data_writer(NULL),
_array_writer(NULL),
_owns_writer(false)
{
initialize();
}
@@ -40,7 +42,9 @@ GeomVertexWriter() :
////////////////////////////////////////////////////////////////////
INLINE GeomVertexWriter::
GeomVertexWriter(GeomVertexData *vertex_data) :
_vertex_data(vertex_data)
_data_writer(new GeomVertexDataPipelineWriter(vertex_data, Thread::get_current_pipeline_stage(), true)),
_array_writer(NULL),
_owns_writer(true)
{
initialize();
}
@@ -54,7 +58,9 @@ GeomVertexWriter(GeomVertexData *vertex_data) :
////////////////////////////////////////////////////////////////////
INLINE GeomVertexWriter::
GeomVertexWriter(GeomVertexData *vertex_data, const string &name) :
_vertex_data(vertex_data)
_data_writer(new GeomVertexDataPipelineWriter(vertex_data, Thread::get_current_pipeline_stage(), true)),
_array_writer(NULL),
_owns_writer(true)
{
initialize();
set_column(name);
@@ -69,7 +75,9 @@ GeomVertexWriter(GeomVertexData *vertex_data, const string &name) :
////////////////////////////////////////////////////////////////////
INLINE GeomVertexWriter::
GeomVertexWriter(GeomVertexData *vertex_data, const InternalName *name) :
_vertex_data(vertex_data)
_data_writer(new GeomVertexDataPipelineWriter(vertex_data, Thread::get_current_pipeline_stage(), true)),
_array_writer(NULL),
_owns_writer(true)
{
initialize();
set_column(name);
@@ -83,7 +91,9 @@ GeomVertexWriter(GeomVertexData *vertex_data, const InternalName *name) :
////////////////////////////////////////////////////////////////////
INLINE GeomVertexWriter::
GeomVertexWriter(GeomVertexArrayData *array_data) :
_array_data(array_data)
_data_writer(NULL),
_array_writer(new GeomVertexArrayDataPipelineWriter(array_data, Thread::get_current_pipeline_stage(), true)),
_owns_writer(true)
{
initialize();
}
@@ -96,22 +106,44 @@ GeomVertexWriter(GeomVertexArrayData *array_data) :
////////////////////////////////////////////////////////////////////
INLINE GeomVertexWriter::
GeomVertexWriter(GeomVertexArrayData *array_data, int column) :
_array_data(array_data)
_data_writer(NULL),
_array_writer(new GeomVertexArrayDataPipelineWriter(array_data, Thread::get_current_pipeline_stage(), true)),
_owns_writer(true)
{
initialize();
set_column(column);
}
////////////////////////////////////////////////////////////////////
// Function: GeomVertexWriter::Constructor
// Access: Public
// Description: Constructs a new writer to process the vertices of
// the indicated data object. This flavor creates the
// writer specifically to process the named data type.
////////////////////////////////////////////////////////////////////
INLINE GeomVertexWriter::
GeomVertexWriter(GeomVertexDataPipelineWriter *data_writer,
const InternalName *name) :
_data_writer(data_writer),
_array_writer(NULL),
_owns_writer(false)
{
initialize();
set_column(name);
}
////////////////////////////////////////////////////////////////////
// Function: GeomVertexWriter::Copy Constructor
// Access: Published
// Description:
// Description: The copy constructor steals ownership of the writer
// pointer.
////////////////////////////////////////////////////////////////////
INLINE GeomVertexWriter::
GeomVertexWriter(const GeomVertexWriter &copy) :
_vertex_data(copy._vertex_data),
_data_writer(copy._data_writer),
_array(copy._array),
_array_data(copy._array_data),
_array_writer(copy._array_writer),
_owns_writer(copy._owns_writer),
_packer(copy._packer),
_stride(copy._stride),
_pointer_begin(copy._pointer_begin),
@@ -119,24 +151,29 @@ GeomVertexWriter(const GeomVertexWriter &copy) :
_pointer(copy._pointer),
_start_row(copy._start_row)
{
((GeomVertexWriter &)copy)._owns_writer = false;
}
////////////////////////////////////////////////////////////////////
// Function: GeomVertexWriter::Copy Assignment Operator
// Access: Published
// Description:
// Description: The copy constructor steals ownership of the writer
// pointer.
////////////////////////////////////////////////////////////////////
INLINE void GeomVertexWriter::
operator = (const GeomVertexWriter &copy) {
_vertex_data = copy._vertex_data;
_data_writer = copy._data_writer;
_array = copy._array;
_array_data = copy._array_data;
_array_writer = copy._array_writer;
_owns_writer = copy._owns_writer;
_packer = copy._packer;
_stride = copy._stride;
_pointer_begin = copy._pointer_begin;
_pointer_end = copy._pointer_end;
_pointer = copy._pointer;
_start_row = copy._start_row;
((GeomVertexWriter &)copy)._owns_writer = false;
}
////////////////////////////////////////////////////////////////////
@@ -146,6 +183,9 @@ operator = (const GeomVertexWriter &copy) {
////////////////////////////////////////////////////////////////////
INLINE GeomVertexWriter::
~GeomVertexWriter() {
if (_owns_writer) {
clear_writer();
}
}
////////////////////////////////////////////////////////////////////
@@ -157,7 +197,10 @@ INLINE GeomVertexWriter::
////////////////////////////////////////////////////////////////////
INLINE GeomVertexData *GeomVertexWriter::
get_vertex_data() const {
return _vertex_data;
if (_data_writer != (GeomVertexDataPipelineWriter *)NULL) {
return _data_writer->get_object();
}
return NULL;
}
////////////////////////////////////////////////////////////////////
@@ -168,7 +211,7 @@ get_vertex_data() const {
////////////////////////////////////////////////////////////////////
INLINE GeomVertexArrayData *GeomVertexWriter::
get_array_data() const {
return _array_data;
return _array_writer->get_object();
}
////////////////////////////////////////////////////////////////////
@@ -186,12 +229,12 @@ get_array_data() const {
////////////////////////////////////////////////////////////////////
INLINE bool GeomVertexWriter::
set_column(int column) {
if (_vertex_data != (GeomVertexData *)NULL) {
return set_column(_vertex_data->get_format()->get_array_with(column),
_vertex_data->get_format()->get_column(column));
if (_data_writer != (GeomVertexDataPipelineWriter *)NULL) {
return set_column(_data_writer->get_format()->get_array_with(column),
_data_writer->get_format()->get_column(column));
}
if (_array_data != (GeomVertexArrayData *)NULL) {
return set_column(0, _array_data->get_array_format()->get_column(column));
if (_array_writer != (GeomVertexArrayDataPipelineWriter *)NULL) {
return set_column(0, _array_writer->get_array_format()->get_column(column));
}
return false;
}
@@ -229,12 +272,12 @@ set_column(const string &name) {
////////////////////////////////////////////////////////////////////
INLINE bool GeomVertexWriter::
set_column(const InternalName *name) {
if (_vertex_data != (GeomVertexData *)NULL) {
return set_column(_vertex_data->get_format()->get_array_with(name),
_vertex_data->get_format()->get_column(name));
if (_data_writer != (GeomVertexDataPipelineWriter *)NULL) {
return set_column(_data_writer->get_format()->get_array_with(name),
_data_writer->get_format()->get_column(name));
}
if (_array_data != (GeomVertexArrayData *)NULL) {
return set_column(0, _array_data->get_array_format()->get_column(name));
if (_array_writer != (GeomVertexArrayDataPipelineWriter *)NULL) {
return set_column(0, _array_writer->get_array_format()->get_column(name));
}
return false;
@@ -759,14 +802,15 @@ get_packer() const {
////////////////////////////////////////////////////////////////////
INLINE void GeomVertexWriter::
set_pointer(int row) {
if (_vertex_data != (const GeomVertexData *)NULL) {
GeomVertexArrayData *array_data = _vertex_data->modify_array(_array);
if (_data_writer != (const GeomVertexDataPipelineWriter *)NULL) {
_data_writer->modify_array(_array);
GeomVertexArrayDataPipelineWriter *array_data = _data_writer->get_array_writer(_array);
_pointer_begin = array_data->modify_data();
_pointer_end = _pointer_begin + array_data->get_data_size_bytes();
} else {
_pointer_begin = _array_data->modify_data();
_pointer_end = _pointer_begin + _array_data->get_data_size_bytes();
_pointer_begin = _array_writer->modify_data();
_pointer_end = _pointer_begin + _array_writer->get_data_size_bytes();
}
quick_set_pointer(row);
}
@@ -783,11 +827,11 @@ quick_set_pointer(int row) {
nassertv(has_column());
#ifdef _DEBUG
if (_vertex_data != (const GeomVertexData *)NULL) {
const GeomVertexArrayData *array_data = _vertex_data->get_array(_array);
nassertv(_pointer_begin == array_data->get_data());
if (_data_writer != (const GeomVertexDataPipelineWriter *)NULL) {
GeomVertexArrayDataPipelineWriter *array_writer = _data_writer->get_array_writer(_array);
nassertv(_pointer_begin == array_writer->get_data());
} else {
nassertv(_pointer_begin == _array_data->get_data());
nassertv(_pointer_begin == _array_writer->get_data());
}
#endif
@@ -804,11 +848,11 @@ INLINE unsigned char *GeomVertexWriter::
inc_pointer() {
#ifdef _DEBUG
nassertr(_pointer < _pointer_end, empty_buffer);
if (_vertex_data != (GeomVertexData *)NULL){
const GeomVertexArrayData *array_data = _vertex_data->get_array(_array);
nassertr(_pointer >= array_data->get_data().p() && _pointer < array_data->get_data().p() + array_data->get_data_size_bytes(), empty_buffer);
if (_data_writer != (GeomVertexDataPipelineWriter *)NULL){
GeomVertexArrayDataPipelineWriter *array_writer = _data_writer->get_array_writer(_array);
nassertr(_pointer >= array_writer->get_data().p() && _pointer < array_writer->get_data().p() + array_writer->get_data_size_bytes(), empty_buffer);
} else {
nassertr(_pointer >= _array_data->get_data().p() && _pointer < _array_data->get_data().p() + _array_data->get_data_size_bytes(), empty_buffer);
nassertr(_pointer >= _array_writer->get_data().p() && _pointer < _array_writer->get_data().p() + _array_writer->get_data_size_bytes(), empty_buffer);
}
#endif
@@ -830,10 +874,10 @@ inc_add_pointer() {
if (_pointer >= _pointer_end) {
// Reset the data pointer.
int write_row = get_write_row();
if (_vertex_data != (GeomVertexData *)NULL) {
_vertex_data->set_num_rows(max(write_row + 1, _vertex_data->get_num_rows()));
if (_data_writer != (GeomVertexDataPipelineWriter *)NULL) {
_data_writer->set_num_rows(max(write_row + 1, _data_writer->get_num_rows()));
} else {
_array_data->set_num_rows(max(write_row + 1, _array_data->get_num_rows()));
_array_writer->set_num_rows(max(write_row + 1, _array_writer->get_num_rows()));
}
set_pointer(write_row);
}
+33 -7
View File
@@ -40,8 +40,8 @@ unsigned char GeomVertexWriter::empty_buffer[100] = { 0 };
////////////////////////////////////////////////////////////////////
bool GeomVertexWriter::
set_column(int array, const GeomVertexColumn *column) {
if (_vertex_data == (GeomVertexData *)NULL &&
_array_data == (GeomVertexArrayData *)NULL) {
if (_data_writer == (GeomVertexDataPipelineWriter *)NULL &&
_array_writer == (GeomVertexArrayDataPipelineWriter *)NULL) {
return false;
}
@@ -56,18 +56,18 @@ set_column(int array, const GeomVertexColumn *column) {
return false;
}
if (_vertex_data != (GeomVertexData *)NULL) {
if (_data_writer != (GeomVertexDataPipelineWriter *)NULL) {
#ifndef NDEBUG
_array = -1;
_packer = NULL;
nassertr(array >= 0 && array < _vertex_data->get_num_arrays(), false);
nassertr(array >= 0 && array < _data_writer->get_num_arrays(), false);
#endif
_array = array;
const GeomVertexArrayData *array_data =_vertex_data->get_array(_array);
_stride = array_data->get_array_format()->get_stride();
GeomVertexArrayDataPipelineWriter *array_writer =_data_writer->get_array_writer(_array);
_stride = array_writer->get_array_format()->get_stride();
} else {
_stride = _array_data->get_array_format()->get_stride();
_stride = _array_writer->get_array_format()->get_stride();
}
_packer = column->_packer;
@@ -103,6 +103,10 @@ output(ostream &out) const {
////////////////////////////////////////////////////////////////////
void GeomVertexWriter::
initialize() {
if (_data_writer != (const GeomVertexDataPipelineWriter *)NULL) {
_data_writer->check_array_writers();
}
_array = 0;
_packer = NULL;
_pointer_begin = NULL;
@@ -110,3 +114,25 @@ initialize() {
_pointer = NULL;
_start_row = 0;
}
////////////////////////////////////////////////////////////////////
// Function: GeomVertexWriter::clear_writer
// Access: Private
// Description: Destructs the GeomVertexDataPipelineWriter, when
// necessary, for instance when this object destructs.
////////////////////////////////////////////////////////////////////
void GeomVertexWriter::
clear_writer() {
nassertv(_owns_writer);
if (_data_writer != (GeomVertexDataPipelineWriter *)NULL) {
delete _data_writer;
_data_writer = NULL;
} else {
nassertv(_array_writer != (GeomVertexArrayDataPipelineWriter *)NULL);
delete _array_writer;
_array_writer = NULL;
}
_owns_writer = false;
}
+10 -2
View File
@@ -81,6 +81,12 @@ PUBLISHED:
INLINE GeomVertexWriter(GeomVertexArrayData *array_data);
INLINE GeomVertexWriter(GeomVertexArrayData *array_data,
int column);
public:
INLINE GeomVertexWriter(GeomVertexDataPipelineWriter *data_writer,
const InternalName *name);
PUBLISHED:
INLINE GeomVertexWriter(const GeomVertexWriter &copy);
INLINE void operator = (const GeomVertexWriter &copy);
INLINE ~GeomVertexWriter();
@@ -144,6 +150,7 @@ private:
class Writer;
void initialize();
void clear_writer();
INLINE void set_pointer(int row);
INLINE void quick_set_pointer(int row);
@@ -155,9 +162,10 @@ private:
// must not keep a pointer to the particular ArrayData we are
// working on (if we do, it may result in an extra copy of the data
// due to holding the reference count).
PT(GeomVertexData) _vertex_data;
GeomVertexDataPipelineWriter *_data_writer;
int _array;
PT(GeomVertexArrayData) _array_data;
GeomVertexArrayDataPipelineWriter *_array_writer;
bool _owns_writer;
GeomVertexColumn::Packer *_packer;
int _stride;
+5 -3
View File
@@ -40,7 +40,7 @@ cp_report_error(ShaderArgInfo &p, const string &msg)
if (p._direction == SAD_out) dstr = "out ";
if (p._direction == SAD_inout) dstr = "inout ";
string tstr = "unknown ";
string tstr = "invalid ";
switch (p._type) {
case SAT_float1: tstr = "float1 "; break;
case SAT_float2: tstr = "float2 "; break;
@@ -51,6 +51,7 @@ cp_report_error(ShaderArgInfo &p, const string &msg)
case SAT_sampler2d: tstr = "sampler2d "; break;
case SAT_sampler3d: tstr = "sampler3d "; break;
case SAT_samplercube: tstr = "samplercube "; break;
case SAT_unknown: tstr = "unknown "; break;
}
string fn = _shader_expansion->get_name();
@@ -70,7 +71,7 @@ cp_errchk_parameter_words(ShaderArgInfo &p, int len)
{
vector_string words;
tokenize(p._name, words, "_");
if (words.size() != len) {
if ((int)words.size() != len) {
cp_report_error(p, "parameter name has wrong number of words");
return false;
}
@@ -138,13 +139,14 @@ cp_errchk_parameter_uniform(ShaderArgInfo &p)
bool ShaderContext::
cp_errchk_parameter_float(ShaderArgInfo &p, int lo, int hi)
{
int nfloat = 0;
int nfloat;
switch (p._type) {
case SAT_float1: nfloat = 1; break;
case SAT_float2: nfloat = 2; break;
case SAT_float3: nfloat = 3; break;
case SAT_float4: nfloat = 4; break;
case SAT_float4x4: nfloat = 16; break;
default: nfloat = 0; break;
}
if ((nfloat < lo)||(nfloat > hi)) {
string msg = "wrong type for parameter: should be float";
+11 -30
View File
@@ -36,20 +36,12 @@ class OcclusionQueryContext;
class GeomContext;
class GeomNode;
class Geom;
class GeomPoint;
class GeomLine;
class GeomLinestrip;
class GeomSprite;
class GeomPolygon;
class GeomQuad;
class GeomTri;
class GeomTristrip;
class GeomTrifan;
class GeomSphere;
class Geom;
class GeomPipelineReader;
class GeomVertexData;
class GeomVertexDataPipelineReader;
class GeomVertexArrayData;
class GeomPrimitive;
class GeomPrimitivePipelineReader;
class GeomTriangles;
class GeomTristrips;
class GeomTrifans;
@@ -177,26 +169,15 @@ public:
// inconvenient to declare each of those types to be friends of this
// class.
virtual void draw_point(GeomPoint *geom, GeomContext *gc) { }
virtual void draw_line(GeomLine *geom, GeomContext *gc) { }
virtual void draw_linestrip(GeomLinestrip *geom, GeomContext *gc) { }
virtual void draw_sprite(GeomSprite *geom, GeomContext *gc) { }
virtual void draw_polygon(GeomPolygon *geom, GeomContext *gc) { }
virtual void draw_quad(GeomQuad *geom, GeomContext *gc) { }
virtual void draw_tri(GeomTri *geom, GeomContext *gc) { }
virtual void draw_tristrip(GeomTristrip *geom, GeomContext *gc) { }
virtual void draw_trifan(GeomTrifan *geom, GeomContext *gc) { }
virtual void draw_sphere(GeomSphere *geom, GeomContext *gc) { }
virtual bool begin_draw_primitives(const Geom *geom,
virtual bool begin_draw_primitives(const GeomPipelineReader *geom_reader,
const GeomMunger *munger,
const GeomVertexData *vertex_data)=0;
virtual void draw_triangles(const GeomTriangles *primitive)=0;
virtual void draw_tristrips(const GeomTristrips *primitive)=0;
virtual void draw_trifans(const GeomTrifans *primitive)=0;
virtual void draw_lines(const GeomLines *primitive)=0;
virtual void draw_linestrips(const GeomLinestrips *primitive)=0;
virtual void draw_points(const GeomPoints *primitive)=0;
const GeomVertexDataPipelineReader *data_reader)=0;
virtual void draw_triangles(const GeomPrimitivePipelineReader *reader)=0;
virtual void draw_tristrips(const GeomPrimitivePipelineReader *reader)=0;
virtual void draw_trifans(const GeomPrimitivePipelineReader *reader)=0;
virtual void draw_lines(const GeomPrimitivePipelineReader *reader)=0;
virtual void draw_linestrips(const GeomPrimitivePipelineReader *reader)=0;
virtual void draw_points(const GeomPrimitivePipelineReader *reader)=0;
virtual void end_draw_primitives()=0;
virtual void framebuffer_copy_to_texture
+4
View File
@@ -69,6 +69,10 @@ PUBLISHED:
Mersenne(unsigned long seed);
unsigned long get_uint31();
enum {
max_value = 0x7fffffff
};
private:
enum {
// Period parameters
+2 -1
View File
@@ -21,6 +21,7 @@
#include "pandabase.h"
#include "pvector.h"
#include "vector_int.h"
#include "luse.h"
#include "mersenne.h"
@@ -57,7 +58,7 @@ protected:
static Mersenne _next_seed;
static bool _got_first_seed;
typedef pvector<int> Index;
typedef vector_int Index;
Index _index;
};
+2 -1
View File
@@ -23,6 +23,7 @@
#include "parametricCurveDrawer.h"
#include "lineSegs.h"
#include "vector_int.h"
////////////////////////////////////////////////////////////////////
@@ -57,7 +58,7 @@ protected:
LVecBase3f _cv_color, _hull_color, _knot_color;
int _num_cvs, _num_hull, _num_knots;
LineSegs _hull, _knots, _cvs;
pvector<int> _knotnums;
vector_int _knotnums;
bool _show_cvs, _show_hull, _show_knots;
@@ -575,7 +575,7 @@ render(pvector< PT(PhysicsObject) >& po_vector, int ttl_particles) {
// First, since this is the only time we have access to the actual particles, do some delayed initialization.
if (_animate_frames || anim_count) {
if (!_birth_list.empty()) {
for (pvector<int>::iterator vIter = _birth_list.begin(); vIter != _birth_list.end(); ++vIter) {
for (vector_int::iterator vIter = _birth_list.begin(); vIter != _birth_list.end(); ++vIter) {
cur_particle = (BaseParticle*)po_vector[*vIter].p();
i = int(NORMALIZED_RAND()*anim_count);
@@ -32,6 +32,7 @@
#include "geomVertexWriter.h"
#include "textureCollection.h"
#include "nodePathCollection.h"
#include "vector_int.h"
class NodePath;
@@ -273,9 +274,9 @@ private:
virtual void resize_pool(int new_size);
int extract_textures_from_node(const NodePath &node_path, NodePathCollection &np_col, TextureCollection &tex_col);
pvector<int> _anim_size; // Holds the number of frames in each animation.
vector_int _anim_size; // Holds the number of frames in each animation.
pvector<int*> _ttl_count; // _ttl_count[i][j] holds the number of particles attached to animation 'i' at frame 'j'.
pvector<int> _birth_list; // Holds the list of particles that need a new random animation to start on.
vector_int _birth_list; // Holds the list of particles that need a new random animation to start on.
};
#include "spriteParticleRenderer.I"
+3 -1
View File
@@ -4,10 +4,12 @@
lerp event gsgbase gobj putil linmath \
downloader express pandabase pstatclient
#begin lib_target
#define TARGET pgraph
// This directory is too big to combine into a single composite file.
#define DONT_COMBINE 1
#define SOURCES \
accumulatedAttribs.I accumulatedAttribs.h \
alphaTestAttrib.I alphaTestAttrib.h \
+2 -1
View File
@@ -27,6 +27,7 @@
#include "sliderTable.h"
#include "pStatCollector.h"
#include "pStatTimer.h"
#include "vector_int.h"
static PStatCollector apply_vertex_collector("*:Flatten:apply:vertex");
static PStatCollector apply_texcoord_collector("*:Flatten:apply:texcoord");
@@ -483,7 +484,7 @@ collect_vertex_data(Geom *geom, int collect_bits) {
// remapping transform indices in the vertices. Each of these has a
// slightly different way to handle the remapping, because they have
// slightly different kinds of data.
typedef pvector<int> IndexMap;
typedef vector_int IndexMap;
if (vdata->get_transform_table() != (TransformTable *)NULL) {
// The TransformTable.
-3
View File
@@ -25,9 +25,6 @@
ShaderPool *ShaderPool::_global_ptr = (ShaderPool *)NULL;
// ??? Is this needed ???
static Loader model_loader;
////////////////////////////////////////////////////////////////////
// Function: ShaderPool::write
// Access: Published, Static
+22
View File
@@ -176,3 +176,25 @@
#end test_bin_target
#begin test_bin_target
#define TARGET test_delete
#define LOCAL_LIBS $[LOCAL_LIBS] pipeline
#define OTHER_LIBS dtoolutil:c dtool:m dtoolconfig:m pystub
#define SOURCES \
test_delete.cxx
#end test_bin_target
#begin test_bin_target
#define TARGET test_atomic
#define LOCAL_LIBS $[LOCAL_LIBS] pipeline
#define OTHER_LIBS dtoolutil:c dtool:m dtoolconfig:m pystub
#define SOURCES \
test_atomic.cxx
#end test_bin_target
+4 -4
View File
@@ -33,10 +33,10 @@ ConfigureFn(config_pipeline) {
}
ConfigVariableInt thread_stack_size
("thread-stack-size", 16384,
PRC_DESC("Specifies the size, in bytes, of the stack that will be created "
"for each newly-created thread. Not all thread implementations "
"respect this value."));
("thread-stack-size", 4194304,
PRC_DESC("Specifies the minimum size, in bytes, of the stack that will be "
"created for each newly-created thread. Not all thread "
"implementations respect this value."));
ConfigVariableBool threads_always_global
("threads-always-global", false,
+62
View File
@@ -35,6 +35,22 @@ CycleDataStageWriter(PipelineCycler<CycleDataType> &cycler, int stage) :
nassertv(_pointer != (CycleDataType *)NULL);
}
////////////////////////////////////////////////////////////////////
// Function: CycleDataStageWriter::Constructor (full)
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
template<class CycleDataType>
INLINE CycleDataStageWriter<CycleDataType>::
CycleDataStageWriter(PipelineCycler<CycleDataType> &cycler, int stage,
bool force_to_0) :
_cycler(&cycler),
_stage(stage)
{
_pointer = _cycler->write_stage_upstream(_stage, force_to_0);
nassertv(_pointer != (CycleDataType *)NULL);
}
////////////////////////////////////////////////////////////////////
// Function: CycleDataStageWriter::Copy Constructor (full)
// Access: Public
@@ -86,6 +102,25 @@ CycleDataStageWriter(PipelineCycler<CycleDataType> &cycler, int stage,
_pointer = _cycler->elevate_read_stage(_stage, take_from.take_pointer());
}
////////////////////////////////////////////////////////////////////
// Function: CycleDataStageWriter::Constructor (full)
// Access: Public
// Description: This flavor of the constructor elevates the pointer
// from the CycleDataStageReader from a read to a write
// pointer (and invalidates the reader).
////////////////////////////////////////////////////////////////////
template<class CycleDataType>
INLINE CycleDataStageWriter<CycleDataType>::
CycleDataStageWriter(PipelineCycler<CycleDataType> &cycler, int stage,
CycleDataStageReader<CycleDataType> &take_from,
bool force_to_0) :
_cycler(&cycler),
_stage(stage)
{
_pointer = _cycler->elevate_read_stage_upstream(_stage, take_from.take_pointer(),
force_to_0);
}
////////////////////////////////////////////////////////////////////
// Function: CycleDataStageWriter::Destructor (full)
// Access: Public
@@ -152,6 +187,17 @@ CycleDataStageWriter(PipelineCycler<CycleDataType> &cycler, int) {
_pointer = cycler.write();
}
////////////////////////////////////////////////////////////////////
// Function: CycleDataStageWriter::Constructor (trivial)
// Access: Public
// Description:
////////////////////////////////////////////////////////////////////
template<class CycleDataType>
INLINE CycleDataStageWriter<CycleDataType>::
CycleDataStageWriter(PipelineCycler<CycleDataType> &cycler, int, bool) {
_pointer = cycler.write();
}
////////////////////////////////////////////////////////////////////
// Function: CycleDataStageWriter::Copy Constructor (trivial)
// Access: Public
@@ -190,6 +236,22 @@ CycleDataStageWriter(PipelineCycler<CycleDataType> &, int,
{
}
////////////////////////////////////////////////////////////////////
// Function: CycleDataStageWriter::Constructor (trivial)
// Access: Public
// Description: This flavor of the constructor elevates the pointer
// from the CycleDataStageReader from a read to a write
// pointer (and invalidates the reader).
////////////////////////////////////////////////////////////////////
template<class CycleDataType>
INLINE CycleDataStageWriter<CycleDataType>::
CycleDataStageWriter(PipelineCycler<CycleDataType> &, int,
CycleDataStageReader<CycleDataType> &take_from,
bool) :
_pointer((CycleDataType *)take_from.take_pointer())
{
}
////////////////////////////////////////////////////////////////////
// Function: CycleDataStageWriter::Destructor (trivial)
// Access: Public
@@ -38,11 +38,16 @@ template<class CycleDataType>
class CycleDataStageWriter {
public:
INLINE CycleDataStageWriter(PipelineCycler<CycleDataType> &cycler, int stage);
INLINE CycleDataStageWriter(PipelineCycler<CycleDataType> &cycler, int stage,
bool force_to_0);
INLINE CycleDataStageWriter(const CycleDataStageWriter<CycleDataType> &copy);
INLINE void operator = (const CycleDataStageWriter<CycleDataType> &copy);
INLINE CycleDataStageWriter(PipelineCycler<CycleDataType> &cycler, int stage,
CycleDataStageReader<CycleDataType> &take_from);
INLINE CycleDataStageWriter(PipelineCycler<CycleDataType> &cycler, int stage,
CycleDataStageReader<CycleDataType> &take_from,
bool force_to_0);
INLINE ~CycleDataStageWriter();
+1 -3
View File
@@ -140,13 +140,11 @@ do_lock() {
}
while (_locking_thread != (Thread *)NULL) {
_cvar.wait();
thread_cat.spam()
<< *this_thread << " wakeup\n";
}
if (thread_cat.is_spam()) {
thread_cat.spam()
<< *this_thread << " awake\n";
<< *this_thread << " awake on " << *this << "\n";
}
this_thread->_blocked_on_mutex = NULL;
+66
View File
@@ -122,6 +122,17 @@ elevate_read_stage(int n, const CycleDataType *pointer) {
return (CycleDataType *)PipelineCyclerBase::elevate_read_stage(n, pointer);
}
////////////////////////////////////////////////////////////////////
// Function: PipelineCycler::elevate_read_stage_upstream (dummy or true)
// Access: Public
// Description: See PipelineCyclerBase::elevate_read_stage_upstream().
////////////////////////////////////////////////////////////////////
template<class CycleDataType>
INLINE CycleDataType *PipelineCycler<CycleDataType>::
elevate_read_stage_upstream(int n, const CycleDataType *pointer, bool force_to_0) {
return (CycleDataType *)PipelineCyclerBase::elevate_read_stage_upstream(n, pointer, force_to_0);
}
////////////////////////////////////////////////////////////////////
// Function: PipelineCycler::write_upstream (dummy or true)
// Access: Public
@@ -144,6 +155,17 @@ write_stage(int n) {
return (CycleDataType *)PipelineCyclerBase::write_stage(n);
}
////////////////////////////////////////////////////////////////////
// Function: PipelineCycler::write_stage_upstream (dummy or true)
// Access: Public
// Description: See PipelineCyclerBase::write_stage_upstream().
////////////////////////////////////////////////////////////////////
template<class CycleDataType>
INLINE CycleDataType *PipelineCycler<CycleDataType>::
write_stage_upstream(int pipeline_stage, bool force_to_0) {
return (CycleDataType *)PipelineCyclerBase::write_stage_upstream(pipeline_stage, force_to_0);
}
////////////////////////////////////////////////////////////////////
// Function: PipelineCycler::cheat (dummy or true)
// Access: Public
@@ -212,6 +234,17 @@ read() const {
return &_typed_data;
}
////////////////////////////////////////////////////////////////////
// Function: PipelineCycler::read_stage (trivial)
// Access: Public
// Description: See PipelineCyclerBase::read_stage().
////////////////////////////////////////////////////////////////////
template<class CycleDataType>
INLINE const CycleDataType *PipelineCycler<CycleDataType>::
read_stage(int) const {
return &_typed_data;
}
////////////////////////////////////////////////////////////////////
// Function: PipelineCycler::write (trivial)
// Access: Public
@@ -245,6 +278,28 @@ elevate_read_upstream(const CycleDataType *, bool) {
return &_typed_data;
}
////////////////////////////////////////////////////////////////////
// Function: PipelineCycler::elevate_read_stage (trivial)
// Access: Public
// Description: See PipelineCyclerBase::elevate_read_stage().
////////////////////////////////////////////////////////////////////
template<class CycleDataType>
INLINE CycleDataType *PipelineCycler<CycleDataType>::
elevate_read_stage(int, const CycleDataType *) {
return &_typed_data;
}
////////////////////////////////////////////////////////////////////
// Function: PipelineCycler::elevate_read_stage_upstream (trivial)
// Access: Public
// Description: See PipelineCyclerBase::elevate_read_stage_upstream().
////////////////////////////////////////////////////////////////////
template<class CycleDataType>
INLINE CycleDataType *PipelineCycler<CycleDataType>::
elevate_read_stage_upstream(int, const CycleDataType *, bool) {
return &_typed_data;
}
////////////////////////////////////////////////////////////////////
// Function: PipelineCycler::write_upstream (trivial)
// Access: Public
@@ -267,6 +322,17 @@ write_stage(int) {
return &_typed_data;
}
////////////////////////////////////////////////////////////////////
// Function: PipelineCycler::write_stage_upstream (trivial)
// Access: Public
// Description: See PipelineCyclerBase::write_stage_upstream().
////////////////////////////////////////////////////////////////////
template<class CycleDataType>
INLINE CycleDataType *PipelineCycler<CycleDataType>::
write_stage_upstream(int, bool) {
return &_typed_data;
}
////////////////////////////////////////////////////////////////////
// Function: PipelineCycler::cheat (trivial)
// Access: Public
+3
View File
@@ -22,6 +22,7 @@
#include "pandabase.h"
#include "pipelineCyclerBase.h"
#include "cyclerHolder.h"
#include "thread.h" // for convenience of code that uses PipelineReader classes
////////////////////////////////////////////////////////////////////
// Class : PipelineCycler
@@ -68,7 +69,9 @@ public:
INLINE CycleDataType *elevate_read(const CycleDataType *pointer);
INLINE CycleDataType *elevate_read_upstream(const CycleDataType *pointer, bool force_to_0);
INLINE CycleDataType *elevate_read_stage(int n, const CycleDataType *pointer);
INLINE CycleDataType *elevate_read_stage_upstream(int n, const CycleDataType *pointer, bool force_to_0);
INLINE CycleDataType *write_upstream(bool force_to_0);
INLINE CycleDataType *write_stage_upstream(int pipeline_stage, bool force_to_0);
INLINE CycleDataType *write_stage(int n);
INLINE CycleDataType *cheat() const;
@@ -353,6 +353,24 @@ write_stage(int n) {
return _data;
}
////////////////////////////////////////////////////////////////////
// Function: PipelineCyclerDummyImpl::write_stage_upstream
// Access: Public
// Description: Returns a pointer suitable for writing to the nth
// stage of the pipeline. This is for special
// applications that need to update the entire pipeline
// at once (for instance, to remove an invalid pointer).
// This pointer should later be released with
// release_write_stage().
////////////////////////////////////////////////////////////////////
INLINE CycleData *PipelineCyclerDummyImpl::
write_stage_upstream(int n, bool) {
TAU_PROFILE("CycleData *PipelineCyclerDummyImpl::write_stage_upstream(int)", " ", TAU_USER);
nassertr(n == 0, (CycleData *)NULL);
_write_count++;
return _data;
}
////////////////////////////////////////////////////////////////////
// Function: PipelineCyclerDummyImpl::elevate_read_stage
// Access: Public
@@ -370,6 +388,23 @@ elevate_read_stage(int n, const CycleData *pointer) {
return write();
}
////////////////////////////////////////////////////////////////////
// Function: PipelineCyclerDummyImpl::elevate_read_stage_upstream
// Access: Public
// Description: Elevates a currently-held read pointer into a write
// pointer. This may or may not change the value of the
// pointer. It is only valid to do this if this is the
// only currently-outstanding read pointer on the
// current stage.
////////////////////////////////////////////////////////////////////
INLINE CycleData *PipelineCyclerDummyImpl::
elevate_read_stage_upstream(int n, const CycleData *pointer, bool) {
TAU_PROFILE("CycleData *PipelineCyclerDummyImpl::elevate_read_stage(int, CycleData *)", " ", TAU_USER);
nassertr(n == 0, NULL);
release_read(pointer);
return write();
}
////////////////////////////////////////////////////////////////////
// Function: PipelineCyclerDummyImpl::release_write_stage
// Access: Public
@@ -70,7 +70,10 @@ public:
INLINE void release_read_stage(int n, const CycleData *pointer) const;
INLINE CycleData *write_upstream(bool force_to_0);
INLINE CycleData *write_stage(int n);
INLINE CycleData *write_stage_upstream(int n, bool force_to_0);
INLINE CycleData *elevate_read_stage(int n, const CycleData *pointer);
INLINE CycleData *elevate_read_stage_upstream(int n, const CycleData *pointer,
bool force_to_0);
INLINE void release_write_stage(int n, CycleData *pointer);
INLINE TypeHandle get_parent_type() const;
@@ -311,6 +311,25 @@ write_stage(int) {
#endif // SIMPLE_STRUCT_POINTERS
}
////////////////////////////////////////////////////////////////////
// Function: PipelineCyclerTrivialImpl::write_stage_upstream
// Access: Public
// Description: Returns a pointer suitable for writing to the nth
// stage of the pipeline. This is for special
// applications that need to update the entire pipeline
// at once (for instance, to remove an invalid pointer).
// This pointer should later be released with
// release_write_stage().
////////////////////////////////////////////////////////////////////
INLINE CycleData *PipelineCyclerTrivialImpl::
write_stage_upstream(int, bool) {
#ifdef SIMPLE_STRUCT_POINTERS
return (CycleData *)this;
#else
return _data;
#endif // SIMPLE_STRUCT_POINTERS
}
////////////////////////////////////////////////////////////////////
// Function: PipelineCyclerTrivialImpl::elevate_read_stage
// Access: Public
@@ -329,6 +348,24 @@ elevate_read_stage(int, const CycleData *) {
#endif // SIMPLE_STRUCT_POINTERS
}
////////////////////////////////////////////////////////////////////
// Function: PipelineCyclerTrivialImpl::elevate_read_stage_upstream
// Access: Public
// Description: Elevates a currently-held read pointer into a write
// pointer. This may or may not change the value of the
// pointer. It is only valid to do this if this is the
// only currently-outstanding read pointer on the
// current stage.
////////////////////////////////////////////////////////////////////
INLINE CycleData *PipelineCyclerTrivialImpl::
elevate_read_stage_upstream(int, const CycleData *, bool) {
#ifdef SIMPLE_STRUCT_POINTERS
return (CycleData *)this;
#else
return _data;
#endif // SIMPLE_STRUCT_POINTERS
}
////////////////////////////////////////////////////////////////////
// Function: PipelineCyclerTrivialImpl::release_write_stage
// Access: Public
@@ -74,7 +74,10 @@ public:
INLINE void release_read_stage(int n, const CycleData *pointer) const;
INLINE CycleData *write_upstream(bool force_to_0);
INLINE CycleData *write_stage(int n);
INLINE CycleData *write_stage_upstream(int n, bool force_to_0);
INLINE CycleData *elevate_read_stage(int n, const CycleData *pointer);
INLINE CycleData *elevate_read_stage_upstream(int n, const CycleData *pointer,
bool force_to_0);
INLINE void release_write_stage(int n, CycleData *pointer);
INLINE TypeHandle get_parent_type() const;
@@ -243,6 +243,41 @@ release_read_stage(int n, const CycleData *pointer) const {
_lock.release();
}
////////////////////////////////////////////////////////////////////
// Function: PipelineCyclerTrueImpl::write_upstream
// Access: Public
// Description: This special variant on write() will automatically
// propagate changes back to upstream pipeline stages.
// If force_to_0 is false, then it propagates back only
// as long as the CycleData pointers are equivalent,
// guaranteeing that it does not modify upstream data
// (other than the modification that will be performed
// by the code that returns this pointer). This is
// particularly appropriate for minor updates, where it
// doesn't matter much if the update is lost, such as
// storing a cached value.
//
// If force_to_0 is true, then the CycleData pointer for
// the current pipeline stage is propagated all the way
// back up to stage 0; after this call, there will be
// only one CycleData pointer that is duplicated in all
// stages between stage 0 and the current stage. This
// may undo some recent changes that were made
// independently at pipeline stage 0 (or any other
// upstream stage). However, it guarantees that the
// change that is to be applied at this pipeline stage
// will stick. This is slightly dangerous because of
// the risk of losing upstream changes; generally, this
// should only be done when you are confident that there
// are no upstream changes to be lost (for instance, for
// an object that has been recently created).
////////////////////////////////////////////////////////////////////
INLINE CycleData *PipelineCyclerTrueImpl::
write_upstream(bool force_to_0) {
int pipeline_stage = Thread::get_current_pipeline_stage();
return write_stage_upstream(pipeline_stage, force_to_0);
}
////////////////////////////////////////////////////////////////////
// Function: PipelineCyclerTrueImpl::elevate_read_stage
// Access: Public
@@ -264,6 +299,27 @@ elevate_read_stage(int n, const CycleData *pointer) {
return new_pointer;
}
////////////////////////////////////////////////////////////////////
// Function: PipelineCyclerTrueImpl::elevate_read_stage_upstream
// Access: Public
// Description: Elevates a currently-held read pointer into a write
// pointer. This may or may not change the value of the
// pointer. It is only valid to do this if this is the
// only currently-outstanding read pointer on the
// indicated stage.
////////////////////////////////////////////////////////////////////
INLINE CycleData *PipelineCyclerTrueImpl::
elevate_read_stage_upstream(int n, const CycleData *pointer, bool force_to_0) {
TAU_PROFILE("CycleData *PipelineCyclerTrueImpl::elevate_read_stage(int, const CycleData *)", " ", TAU_USER);
#ifdef _DEBUG
nassertr(n >= 0 && n < _num_stages, NULL);
nassertr(_data[n] == pointer, NULL);
#endif
CycleData *new_pointer = write_stage_upstream(n, force_to_0);
_lock.release();
return new_pointer;
}
////////////////////////////////////////////////////////////////////
// Function: PipelineCyclerTrueImpl::release_write_stage
// Access: Public
+42 -66
View File
@@ -130,39 +130,52 @@ PipelineCyclerTrueImpl::
}
////////////////////////////////////////////////////////////////////
// Function: PipelineCyclerTrueImpl::write_upstream
// Function: PipelineCyclerTrueImpl::write_stage
// Access: Public
// Description: This special variant on write() will automatically
// propagate changes back to upstream pipeline stages.
// If force_to_0 is false, then it propagates back only
// as long as the CycleData pointers are equivalent,
// guaranteeing that it does not modify upstream data
// (other than the modification that will be performed
// by the code that returns this pointer). This is
// particularly appropriate for minor updates, where it
// doesn't matter much if the update is lost, such as
// storing a cached value.
//
// If force_to_0 is true, then the CycleData pointer for
// the current pipeline stage is propagated all the way
// back up to stage 0; after this call, there will be
// only one CycleData pointer that is duplicated in all
// stages between stage 0 and the current stage. This
// may undo some recent changes that were made
// independently at pipeline stage 0 (or any other
// upstream stage). However, it guarantees that the
// change that is to be applied at this pipeline stage
// will stick. This is slightly dangerous because of
// the risk of losing upstream changes; generally, this
// should only be done when you are confident that there
// are no upstream changes to be lost (for instance, for
// an object that has been recently created).
// Description: Returns a pointer suitable for writing to the nth
// stage of the pipeline. This is for special
// applications that need to update the entire pipeline
// at once (for instance, to remove an invalid pointer).
// This pointer should later be released with
// release_write_stage().
////////////////////////////////////////////////////////////////////
CycleData *PipelineCyclerTrueImpl::
write_upstream(bool force_to_0) {
write_stage(int pipeline_stage) {
_lock.lock();
#ifndef NDEBUG
nassertd(pipeline_stage >= 0 && pipeline_stage < _num_stages) {
_lock.release();
return NULL;
}
#endif // NDEBUG
CycleData *old_data = _data[pipeline_stage];
if (old_data->get_ref_count() != 1) {
// Copy-on-write.
_data[pipeline_stage] = old_data->make_copy();
// Now we have differences between some of the data pointers, so
// we're "dirty". Mark it so.
if (!_dirty) {
_pipeline->add_dirty_cycler(this);
}
}
return _data[pipeline_stage];
}
////////////////////////////////////////////////////////////////////
// Function: PipelineCyclerTrueImpl::write_stage_upstream
// Access: Public
// Description: This special variant on write_stage() will
// automatically propagate changes back to upstream
// pipeline stages. See write_upstream().
////////////////////////////////////////////////////////////////////
CycleData *PipelineCyclerTrueImpl::
write_stage_upstream(int pipeline_stage, bool force_to_0) {
_lock.lock();
int pipeline_stage = Thread::get_current_pipeline_stage();
#ifndef NDEBUG
nassertd(pipeline_stage >= 0 && pipeline_stage < _num_stages) {
@@ -218,43 +231,6 @@ write_upstream(bool force_to_0) {
return _data[pipeline_stage];
}
////////////////////////////////////////////////////////////////////
// Function: PipelineCyclerTrueImpl::write_stage
// Access: Public
// Description: Returns a pointer suitable for writing to the nth
// stage of the pipeline. This is for special
// applications that need to update the entire pipeline
// at once (for instance, to remove an invalid pointer).
// This pointer should later be released with
// release_write_stage().
////////////////////////////////////////////////////////////////////
CycleData *PipelineCyclerTrueImpl::
write_stage(int pipeline_stage) {
_lock.lock();
#ifndef NDEBUG
nassertd(pipeline_stage >= 0 && pipeline_stage < _num_stages) {
_lock.release();
return NULL;
}
#endif // NDEBUG
CycleData *old_data = _data[pipeline_stage];
if (old_data->get_ref_count() != 1) {
// Copy-on-write.
_data[pipeline_stage] = old_data->make_copy();
// Now we have differences between some of the data pointers, so
// we're "dirty". Mark it so.
if (!_dirty) {
_pipeline->add_dirty_cycler(this);
}
}
return _data[pipeline_stage];
}
////////////////////////////////////////////////////////////////////
// Function: PipelineCyclerTrueImpl::cycle
// Access: Private
+3 -1
View File
@@ -73,9 +73,11 @@ public:
INLINE int get_num_stages();
INLINE const CycleData *read_stage(int n) const;
INLINE void release_read_stage(int n, const CycleData *pointer) const;
CycleData *write_upstream(bool force_to_0);
INLINE CycleData *write_upstream(bool force_to_0);
CycleData *write_stage(int pipeline_stage);
CycleData *write_stage_upstream(int pipeline_stage, bool force_to_0);
INLINE CycleData *elevate_read_stage(int n, const CycleData *pointer);
INLINE CycleData *elevate_read_stage_upstream(int n, const CycleData *pointer, bool force_to_0);
INLINE void release_write_stage(int n, CycleData *pointer);
INLINE TypeHandle get_parent_type() const;
+1
View File
@@ -1,3 +1,4 @@
BEGIN_EXCLUDE_LIST
void *ThreadPosixImpl::root_func#
void *ThreadWin32Impl::root_func#
END_EXCLUDE_LIST
+142
View File
@@ -0,0 +1,142 @@
// Filename: test_delete.cxx
// Created by: drose (18Apr06)
//
////////////////////////////////////////////////////////////////////
//
// PANDA 3D SOFTWARE
// Copyright (c) 2001 - 2004, Disney Enterprises, Inc. All rights reserved
//
// All use of this software is subject to the terms of the Panda 3d
// Software license. You should have received a copy of this license
// along with this source code; you will also find a current copy of
// the license at http://etc.cmu.edu/panda3d/docs/license/ .
//
// To contact the maintainers of this program write to
// panda3d-general@lists.sourceforge.net .
//
////////////////////////////////////////////////////////////////////
#include "pandabase.h"
#include "thread.h"
#include "pmutex.h"
#include "mutexHolder.h"
#include "deletedChain.h"
// This is the number of passes to make per thread.
static const int num_passes = 100;
// This is the number of doobers to allocate in each pass.
static const int num_doobers_per_pass = 1000000;
// This is the max number to allocate in each chunk.
static const int max_doobers_per_chunk = 1000;
// The number of threads to spawn.
static const int number_of_threads = 4;
#ifdef WIN32_VC
static int last_rand = 0;
#endif /* __WIN32__ */
Mutex rand_mutex;
static double
random_f(double max) {
MutexHolder l(rand_mutex);
int i = rand();
#ifdef WIN32_VC
last_rand = i;
#endif /* __WIN32__ */
return max * (double)i / (double)RAND_MAX;
}
#define OUTPUT(stuff) { \
MutexHolder holder(Mutex::_notify_mutex); \
stuff; \
}
class Doober {
public:
Doober(int counter) : _counter(counter) {
}
~Doober() {
nassertv(_counter != -1);
_counter = -1;
}
ALLOC_DELETED_CHAIN(Doober);
int _counter;
};
typedef pvector<Doober *> Doobers;
class MyThread : public Thread {
public:
MyThread(const string &name) : Thread(name, name)
{
}
virtual void
thread_main() {
OUTPUT(nout << *this << " beginning.\n");
#ifdef WIN32_VC
rand_mutex.lock();
srand(last_rand);
rand_mutex.release();
random_f(1.0);
#endif /* __WIN32__ */
Doobers doobers;
for (int i = 0; i < num_passes; ++i) {
int counter = 0;
while (counter < num_doobers_per_pass) {
int num_alloc = (int)random_f(max_doobers_per_chunk);
for (int i = 0; i < num_alloc; ++i) {
doobers.push_back(new Doober(++counter));
}
int num_del = (int)random_f(max_doobers_per_chunk);
num_del = min(num_del, (int)doobers.size());
for (int j = 0; j < num_del; ++j) {
assert(!doobers.empty());
delete doobers.back();
doobers.pop_back();
}
}
OUTPUT(nout << get_name() << " has " << doobers.size() << " doobers.\n");
}
OUTPUT(nout << *this << " ending.\n");
}
};
int
main(int argc, char *argv[]) {
OUTPUT(nout << "Making " << number_of_threads << " threads.\n");
typedef pvector< PT(MyThread) > Threads;
Threads threads;
PT(MyThread) thread = new MyThread("a");
threads.push_back(thread);
thread->start(TP_normal, true, true);
for (int i = 1; i < number_of_threads; ++i) {
char name = 'a' + i;
PT(MyThread) thread = new MyThread(string(1, name));
threads.push_back(thread);
thread->start(TP_normal, true, true);
}
// Now join all the threads.
Threads::iterator ti;
for (ti = threads.begin(); ti != threads.end(); ++ti) {
(*ti)->join();
}
exit(0);
}
+2 -2
View File
@@ -35,8 +35,6 @@
static int last_rand = 0;
#endif /* __WIN32__ */
#define PRINTMSG(x) { MutexHolder l(Mutex::_notify_mutex); x << flush; }
Mutex rand_mutex;
static double random_f(double max)
@@ -49,6 +47,8 @@ static double random_f(double max)
return max * (double)i / (double)RAND_MAX;
}
#define PRINTMSG(x) { MutexHolder l(Mutex::_notify_mutex); x << flush; }
// n philosophers sharing n chopsticks. Philosophers are poor folk and can't
// afford luxuries like 2 chopsticks per person.
#define N_DINERS 5
+7 -1
View File
@@ -84,9 +84,15 @@ start(ThreadPriority priority, bool global, bool joinable) {
_detached = true;
}
int result = pthread_attr_setstacksize(&attr, thread_stack_size);
if (result != 0) {
thread_cat.warning()
<< "Unable to set stack size.\n";
}
// Ensure the thread has "system" scope, which should ensure it can
// run in parallel with other threads.
int result = pthread_attr_setscope(&attr, PTHREAD_SCOPE_SYSTEM);
result = pthread_attr_setscope(&attr, PTHREAD_SCOPE_SYSTEM);
if (result != 0) {
thread_cat.warning()
<< "Unable to set system scope.\n";
+37 -32
View File
@@ -146,45 +146,50 @@ join() {
////////////////////////////////////////////////////////////////////
DWORD ThreadWin32Impl::
root_func(LPVOID data) {
ThreadWin32Impl *self = (ThreadWin32Impl *)data;
BOOL result = TlsSetValue(_pt_ptr_index, self->_parent_obj);
nassertr(result, 1);
TAU_REGISTER_THREAD();
{
self->_mutex.lock();
nassertd(self->_status == S_start_called) {
TAU_PROFILE("void ThreadPosixImpl::root_func()", " ", TAU_USER);
ThreadWin32Impl *self = (ThreadWin32Impl *)data;
BOOL result = TlsSetValue(_pt_ptr_index, self->_parent_obj);
nassertr(result, 1);
{
self->_mutex.lock();
nassertd(self->_status == S_start_called) {
self->_mutex.release();
return 1;
}
self->_status = S_running;
self->_cv.signal();
self->_mutex.release();
return 1;
}
self->_status = S_running;
self->_cv.signal();
self->_mutex.release();
}
self->_parent_obj->thread_main();
if (thread_cat.is_debug()) {
thread_cat.debug()
<< "Terminating thread " << self->_parent_obj->get_name()
<< ", count = " << self->_parent_obj->get_ref_count() << "\n";
}
{
self->_mutex.lock();
nassertd(self->_status == S_running) {
self->_parent_obj->thread_main();
if (thread_cat.is_debug()) {
thread_cat.debug()
<< "Terminating thread " << self->_parent_obj->get_name()
<< ", count = " << self->_parent_obj->get_ref_count() << "\n";
}
{
self->_mutex.lock();
nassertd(self->_status == S_running) {
self->_mutex.release();
return 1;
}
self->_status = S_finished;
self->_cv.signal();
self->_mutex.release();
return 1;
}
self->_status = S_finished;
self->_cv.signal();
self->_mutex.release();
// Now drop the parent object reference that we grabbed in start().
// This might delete the parent object, and in turn, delete the
// ThreadWin32Impl object.
unref_delete(self->_parent_obj);
}
// Now drop the parent object reference that we grabbed in start().
// This might delete the parent object, and in turn, delete the
// ThreadWin32Impl object.
unref_delete(self->_parent_obj);
return 0;
}
+3 -3
View File
@@ -409,7 +409,7 @@ make_collector_with_name(int parent_index, const string &name) {
// initialize_collector_def(this, collector->_def);
// We need one PerThreadData for each thread.
while (collector->_per_thread.size() < _num_threads) {
while ((int)collector->_per_thread.size() < _num_threads) {
collector->_per_thread.push_back(PerThreadData());
}
add_collector(collector);
@@ -787,8 +787,8 @@ add_level(int collector_index, int thread_index, float increment) {
float PStatClient::
get_level(int collector_index, int thread_index) const {
#ifdef _DEBUG
nassertv(collector_index >= 0 && collector_index < AtomicAdjust::get(_num_collectors));
nassertv(thread_index >= 0 && thread_index < AtomicAdjust::get(_num_threads));
nassertr(collector_index >= 0 && collector_index < AtomicAdjust::get(_num_collectors), 0.0f);
nassertr(thread_index >= 0 && thread_index < AtomicAdjust::get(_num_threads), 0.0f);
#endif
Collector *collector = get_collector_ptr(collector_index);
+1 -2
View File
@@ -16,7 +16,7 @@
//
////////////////////////////////////////////////////////////////////
#include "datagramInputFile.h"
#include "numeric_types.h"
#include "datagramIterator.h"
#include "profileTimer.h"
@@ -24,7 +24,6 @@
#include "config_express.h"
#include "virtualFileSystem.h"
#include "streamReader.h"
#include "datagramInputFile.h"
////////////////////////////////////////////////////////////////////
// Function: DatagramInputFile::open
+1 -1
View File
@@ -22,7 +22,7 @@
config_windisplay.cxx winGraphicsPipe.cxx
#define SOURCES \
winGraphicsWindow.cxx $[INCLUDED_SOURCES] $[INSTALL_HEADERS]
winGraphicsWindow.cxx $[INSTALL_HEADERS]
#define WIN_SYS_LIBS Imm32.lib winmm.lib kernel32.lib oldnames.lib user32.lib gdi32.lib
+2 -2
View File
@@ -336,7 +336,7 @@ convert_triangles(const GeomVertexData *vertex_data,
Vertexf vertex = reader.get_data3f();
egg_vert.set_pos(LCAST(double, vertex * net_mat));
if (vertex_data->has_normal()) {
if (vertex_data->has_column(InternalName::get_normal())) {
reader.set_column(InternalName::get_normal());
Normalf normal = reader.get_data3f();
egg_vert.set_normal(LCAST(double, normal * net_mat));
@@ -346,7 +346,7 @@ convert_triangles(const GeomVertexData *vertex_data,
} else if (!has_color_off) {
Colorf color(1.0f, 1.0f, 1.0f, 1.0f);
if (vertex_data->has_color()) {
if (vertex_data->has_column(InternalName::get_color())) {
reader.set_column(InternalName::get_color());
color = reader.get_data4f();
}