Main Page   Namespace List   Class Hierarchy   Alphabetical List   Compound List   File List   Compound Members   File Members   Related Pages  

VMDDisplayList.C

Go to the documentation of this file.
00001 /***************************************************************************
00002  *cr
00003  *cr            (C) Copyright 1995-2011 The Board of Trustees of the
00004  *cr                        University of Illinois
00005  *cr                         All Rights Reserved
00006  *cr
00007  ***************************************************************************/
00008 
00009 /***************************************************************************
00010  * RCS INFORMATION:
00011  *
00012  *      $RCSfile: VMDDisplayList.C,v $
00013  *      $Author: johns $        $Locker:  $             $State: Exp $
00014  *      $Revision: 1.37 $      $Date: 2011/06/01 19:35:59 $
00015  *
00016  ***************************************************************************
00017  * DESCRIPTION:
00018  *   Display list data structure used to hold all of the rendering commands
00019  *   VMD generates and interprets in order to do its 3-D rendering. 
00020  ***************************************************************************/
00021 
00022 #include "VMDDisplayList.h"
00023 #include "VMDApp.h"
00024 #include "Matrix4.h"
00025 #include "Inform.h"
00026 
00027 // required word size alignment in bytes, 16 bytes is large enough for 
00028 // all currently known systems.
00029 #define ALLOC_ALIGNMENT 16 
00030 #define ALLOC_ALIGNMASK (ALLOC_ALIGNMENT - 1)
00031 
00032 // Initial number of bytes in the display list memory block; not allocated
00033 // until the list receives its first command.
00034 
00035 // Typical "empty" representations need about 64 bytes to hold their 
00036 // initial material on, line thickness and resolution parameters.
00037 #define BASE_DISPLAYLIST_SIZE  64
00038 
00039 // once the representation goes past being empty, it's likely going to need
00040 // a lot more space in subsequent allocations, so the next growth step is
00041 // much bigger to reduce the total number of calls without creating too much
00042 // memory fragmentation for simple representations.
00043 #define GROWN_DISPLAYLIST_SIZE 16384
00044 
00045 void *VMDDisplayList::operator new(size_t n) {
00046   return vmd_alloc(n);
00047 }
00048 
00049 void VMDDisplayList::operator delete(void *p, size_t) {
00050   vmd_dealloc(p);
00051 }
00052 
00053 VMDDisplayList::VMDDisplayList() {
00054   materialtag = 0;
00055   serial=0;
00056   cacheskip=0;
00057   pbc = PBC_NONE;
00058   npbc = 1;
00059 
00060   // Begin with no memory allocated for the pool; many display lists,
00061   // like those for DrawMolecule, DrawForce, and MoleculeGraphics, spend
00062   // their whole lives with no commands, so it's wasteful to allocate
00063   // anything for them.
00064   // 
00065   // XXX In fact, DrawForce and MoleculeGraphics are creating single-element
00066   // display lists that contain nothing but DMATERIALON.  This should be
00067   // fixed; better might even be to not create these Displayables at all 
00068   // until/unless they are needed.  
00069   listsize = 0;
00070   poolsize = 0;
00071   poolused = 0;
00072   pool = NULL;
00073 }
00074 
00075 VMDDisplayList::~VMDDisplayList() {
00076   if (pool) vmd_dealloc(pool);
00077 }
00078 
00079 void *VMDDisplayList::append(int code, long size) {
00080   unsigned long neededBytes = (sizeof(CommandHeader) + size + ALLOC_ALIGNMASK) & ~(ALLOC_ALIGNMASK);
00081   if (neededBytes + poolused > poolsize) {
00082     unsigned long newsize;
00083     if (!pool) {
00084       newsize = (neededBytes < BASE_DISPLAYLIST_SIZE) ? 
00085         BASE_DISPLAYLIST_SIZE : neededBytes;
00086     } else {
00087       newsize = (unsigned long) (1.2f * (poolsize + neededBytes));
00088       if (newsize < GROWN_DISPLAYLIST_SIZE)
00089         newsize = GROWN_DISPLAYLIST_SIZE;
00090     }
00091 //printf("bumping displist size from %d to %d to handle %d from cmd %d\n", poolsize, newsize, size, code);
00092     char *tmp = (char *) vmd_resize_alloc(pool, poolused, newsize);
00093     // check for failed allocations
00094     if (!tmp) {
00095       msgErr << "Failed to increase display list memory pool size, system out of memory" << sendmsg;
00096       msgErr << "  Previous pool size: " << ((unsigned long) (poolsize / (1024*1024))) << "MB" << sendmsg;
00097       msgErr << "  Requested pool size: " << ((unsigned long) (newsize / (1024*1024))) << "MB" << sendmsg;
00098       return NULL;
00099     }
00100     poolsize = newsize;
00101     pool = tmp;
00102   }
00103   // store header and size of header + data into pool
00104   CommandHeader *header = (CommandHeader *)(pool + poolused);
00105   poolused += neededBytes;
00106 
00107   header->code = code;
00108   header->size = neededBytes;
00109 
00110   // return pointer to data following header
00111   ++listsize;
00112   return header+1;
00113 }
00114 
00115 void VMDDisplayList::reset_and_free(unsigned long newserial) {
00116   // if we used less than 1/4 of the total pool size, trim the pool
00117   // back to empty so that we don't hog memory.
00118   if (poolsize > BASE_DISPLAYLIST_SIZE && 
00119       poolused / (float)poolsize < 0.25f) {
00120     vmd_dealloc(pool);
00121     pool = NULL;
00122     poolsize = 0;
00123   }
00124   poolused = 0;
00125   listsize = 0;
00126   serial = newserial;
00127 }
00128 
00129 int VMDDisplayList::set_clip_normal(int i, const float *normal) { 
00130   if (i < 0 || i >= VMD_MAX_CLIP_PLANE) return 0;
00131   float length = norm(normal);
00132   if (!length) return 0;
00133   clipplanes[i].normal[0] = normal[0]/length;
00134   clipplanes[i].normal[1] = normal[1]/length;
00135   clipplanes[i].normal[2] = normal[2]/length;
00136   return 1;
00137 }
00138 
00139 int VMDDisplayList::set_clip_center(int i, const float *center) { 
00140   if (i < 0 || i >= VMD_MAX_CLIP_PLANE) return 0;
00141   clipplanes[i].center[0] = center[0];
00142   clipplanes[i].center[1] = center[1];
00143   clipplanes[i].center[2] = center[2];
00144   return 1;
00145 }
00146 
00147 int VMDDisplayList::set_clip_color(int i, const float *color) { 
00148   if (i < 0 || i >= VMD_MAX_CLIP_PLANE) return 0;
00149   clipplanes[i].color[0] = color[0];
00150   clipplanes[i].color[1] = color[1];
00151   clipplanes[i].color[2] = color[2];
00152   return 1;
00153 }
00154 
00155 int VMDDisplayList::set_clip_status(int i, int mode) {
00156   if (i < 0 || i >= VMD_MAX_CLIP_PLANE) return 0;
00157   clipplanes[i].mode = mode;
00158   return 1;
00159 }
00160 
00161   

Generated on Sat May 25 01:49:12 2013 for VMD (current) by doxygen1.2.14 written by Dimitri van Heesch, © 1997-2002