Browse Source

changes from Gogg: startup optimization, freetype faces, string tokenizer

David Rose 16 năm trước cách đây
mục cha
commit
8a64a06946

+ 8 - 0
panda/src/downloader/socketStream.cxx

@@ -246,6 +246,14 @@ bool SSWriter::
 send_datagram(const Datagram &dg) {
   Datagram header;
   if (_tcp_header_size == 2) {
+    if (dg.get_length() >= 0x10000) {
+      downloader_cat.error()
+        << "Attempt to send TCP datagram of " << dg.get_length()
+        << " bytes--too long!\n";
+      nassert_raise("Datagram too long");
+      return false;
+    }
+    
     header.add_uint16(dg.get_length());
   } else if (_tcp_header_size == 4) {
     header.add_uint32(dg.get_length());

+ 5 - 0
panda/src/dxgsg9/config_dxgsg9.cxx

@@ -87,6 +87,11 @@ ConfigVariableDouble dx_depth_bias_scale
           "amount by which we slide the viewport back to achieve the effect "
           "of a depth bias.  It should generally be a small number."));
 
+ConfigVariableBool dx_count_all_cards_memory
+("dx-count-all-cards-memory", true,
+ PRC_DESC("Set this to false to skip the counting of extra cards memory "
+          "via DX7 calls."));
+
 #ifndef NDEBUG
 // debugging flag
 // values are same as D3DCULL enumtype, 0 - no force, 1 - force none, 2 - force CW, 3 - force CCW

+ 1 - 0
panda/src/dxgsg9/config_dxgsg9.h

@@ -35,6 +35,7 @@ extern ConfigVariableBool dx_use_triangle_mipgen_filter;
 extern ConfigVariableBool dx_broken_max_index;
 extern ConfigVariableBool dx_broken_depth_bias;
 extern ConfigVariableDouble dx_depth_bias_scale;
+extern ConfigVariableBool dx_count_all_cards_memory;
 
 // debug flags we might want to use in full optimized build
 extern ConfigVariableBool dx_ignore_mipmaps;

+ 5 - 1
panda/src/dxgsg9/wdxGraphicsPipe9.cxx

@@ -227,7 +227,11 @@ init() {
 
   Init_D3DFORMAT_map();
 
-  return find_all_card_memavails();
+  if (dx_count_all_cards_memory){
+    return find_all_card_memavails();
+  }
+
+  return true;
 
  error:
   return false;

+ 2 - 0
panda/src/pnmtext/Sources.pp

@@ -13,12 +13,14 @@
     
   #define SOURCES \
     config_pnmtext.cxx config_pnmtext.h \
+    freetypeFace.cxx freetypeFace.h freetypeFace.I \
     freetypeFont.cxx freetypeFont.h freetypeFont.I \
     pnmTextGlyph.cxx pnmTextGlyph.h pnmTextGlyph.I \
     pnmTextMaker.cxx pnmTextMaker.h pnmTextMaker.I
 
   #define INSTALL_HEADERS \
     config_pnmtext.h \
+    freetypeFace.h freetypeFace.I \
     freetypeFont.h freetypeFont.I \
     pnmTextGlyph.h pnmTextGlyph.I \
     pnmTextMaker.h pnmTextMaker.I

+ 33 - 0
panda/src/pnmtext/freetypeFace.I

@@ -0,0 +1,33 @@
+// Filename: freetypeFace.I
+// Created by:  gogg (16Nov09)
+//
+////////////////////////////////////////////////////////////////////
+//
+// PANDA 3D SOFTWARE
+// Copyright (c) Carnegie Mellon University.  All rights reserved.
+//
+// All use of this software is subject to the terms of the revised BSD
+// license.  You should have received a copy of this license along
+// with this source code in a file named "LICENSE."
+//
+////////////////////////////////////////////////////////////////////
+
+////////////////////////////////////////////////////////////////////
+//     Function: TextFont::get_face
+//       Access: Published
+//  Description: Retrieves the internal freetype face.
+////////////////////////////////////////////////////////////////////
+INLINE FT_Face FreetypeFace::
+get_face() {
+  return _face;
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: TextFont::set_face
+//       Access: Published
+//  Description: Sets the internal freetype face.
+////////////////////////////////////////////////////////////////////
+INLINE void FreetypeFace::
+set_face(FT_Face face) {
+  _face = face;
+}

+ 43 - 0
panda/src/pnmtext/freetypeFace.cxx

@@ -0,0 +1,43 @@
+// Filename: freetypeFace.cxx
+// Created by:  gogg (16Nov09)
+//
+////////////////////////////////////////////////////////////////////
+//
+// PANDA 3D SOFTWARE
+// Copyright (c) Carnegie Mellon University.  All rights reserved.
+//
+// All use of this software is subject to the terms of the revised BSD
+// license.  You should have received a copy of this license along
+// with this source code in a file named "LICENSE."
+//
+////////////////////////////////////////////////////////////////////
+
+#include "freetypeFace.h"
+
+#ifdef HAVE_FREETYPE
+
+TypeHandle FreetypeFace::_type_handle;
+
+////////////////////////////////////////////////////////////////////
+//     Function: FreetypeFace::Constructor
+//       Access: Public
+//  Description: 
+////////////////////////////////////////////////////////////////////
+FreetypeFace::
+FreetypeFace() {
+  _face = NULL;
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: FreetypeFace::Destructor
+//       Access: Public
+//  Description: 
+////////////////////////////////////////////////////////////////////
+FreetypeFace::
+~FreetypeFace() {
+  if (_face != NULL){
+    FT_Done_Face(_face);
+  }
+}
+
+#endif  // HAVE_FREETYPE

+ 77 - 0
panda/src/pnmtext/freetypeFace.h

@@ -0,0 +1,77 @@
+// Filename: freetypeFont.h
+// Created by:  gogg (16Nov09)
+//
+////////////////////////////////////////////////////////////////////
+//
+// PANDA 3D SOFTWARE
+// Copyright (c) Carnegie Mellon University.  All rights reserved.
+//
+// All use of this software is subject to the terms of the revised BSD
+// license.  You should have received a copy of this license along
+// with this source code in a file named "LICENSE."
+//
+////////////////////////////////////////////////////////////////////
+
+#ifndef FREETYPEFACE_H
+#define FREETYPEFACE_H
+
+#include "pandabase.h"
+
+#ifdef HAVE_FREETYPE
+
+//#include "config_pnmtext.h"
+//#include "filename.h"
+//#include "pvector.h"
+//#include "pmap.h"
+//#include "pnmImage.h"
+#include "typedReferenceCount.h"
+#include "namable.h"
+
+#include <ft2build.h>
+#include FT_FREETYPE_H
+
+////////////////////////////////////////////////////////////////////
+//       Class : FreetypeFont
+// Description : This is a reference-counted wrapper for the
+//               freetype font face object (FT_Face).
+//               It's used by the FreetypeFont class to store a face
+//               that can be shared between copied instances.
+////////////////////////////////////////////////////////////////////
+class EXPCL_PANDA_PNMTEXT FreetypeFace : public TypedReferenceCount, public Namable {
+public:
+  FreetypeFace();
+
+PUBLISHED:
+  ~FreetypeFace();
+
+  INLINE FT_Face get_face();
+  INLINE void set_face(FT_Face face);
+
+private:
+  FT_Face _face;
+
+
+public:
+  static TypeHandle get_class_type() {
+    return _type_handle;
+  }
+  static void init_type() {
+    TypedReferenceCount::init_type();
+    register_type(_type_handle, "FreetypeFace",
+                  TypedReferenceCount::get_class_type());
+  }
+  virtual TypeHandle get_type() const {
+    return get_class_type();
+  }
+  virtual TypeHandle force_init_type() {init_type(); return get_class_type();}
+
+private:
+  static TypeHandle _type_handle;
+};
+
+
+#include "freetypeFace.I"
+
+#endif  // HAVE_FREETYPE
+
+#endif

+ 33 - 27
panda/src/pnmtext/freetypeFont.cxx

@@ -42,6 +42,8 @@ FreetypeFont::
 FreetypeFont() {
   _font_loaded = false;
 
+  _face = new FreetypeFace();
+
   _point_size = text_point_size;
   _requested_pixels_per_unit = text_pixels_per_unit;
   _tex_pixels_per_unit = text_pixels_per_unit;
@@ -84,10 +86,12 @@ load_font(const Filename &font_filename, int face_index) {
   vfs->resolve_filename(path, get_model_path());
   exists = vfs->read_file(path, _raw_font_data, true);
   if (exists) {
+    FT_Face face;
     error = FT_New_Memory_Face(_ft_library, 
                                (const FT_Byte *)_raw_font_data.data(),
                                _raw_font_data.length(),
-                               face_index, &_face);
+                               face_index, &face);
+    _face->set_face(face);
   }
 
   if (!exists) {
@@ -127,9 +131,11 @@ load_font(const char *font_data, int data_length, int face_index) {
   unload_font();
 
   int error;
+  FT_Face face;
   error = FT_New_Memory_Face(_ft_library, 
                              (const FT_Byte *)font_data, data_length,
-                             face_index, &_face);
+                             face_index, &face);
+  _face->set_face(face);
 
   if (error == FT_Err_Unknown_File_Format) {
     pnmtext_cat.error()
@@ -153,7 +159,7 @@ load_font(const char *font_data, int data_length, int face_index) {
 void FreetypeFont::
 unload_font() {
   if (_font_loaded) {
-    FT_Done_Face(_face);
+    _face = NULL;
     _font_loaded = false;
   }
 }
@@ -178,7 +184,7 @@ load_glyph(int glyph_index, bool prerender) {
     flags = 0;
   }
 
-  int error = FT_Load_Glyph(_face, glyph_index, flags);
+  int error = FT_Load_Glyph(_face->get_face(), glyph_index, flags);
   if (error) {
     pnmtext_cat.error()
       << "Unable to render glyph " << glyph_index << "\n";
@@ -257,10 +263,10 @@ copy_bitmap_to_pnmimage(const FT_Bitmap &bitmap, PNMImage &image) {
 ////////////////////////////////////////////////////////////////////
 bool FreetypeFont::
 font_loaded() {
-  string name = _face->family_name;
-  if (_face->style_name != NULL) {
+  string name = _face->get_face()->family_name;
+  if (_face->get_face()->style_name != NULL) {
     name += " ";
-    name += _face->style_name;
+    name += _face->get_face()->style_name;
   }
   set_name(name);
   
@@ -271,29 +277,29 @@ font_loaded() {
 
   if (pnmtext_cat.is_debug()) {
     pnmtext_cat.debug()
-      << name << " has " << _face->num_charmaps << " charmaps:\n";
-    for (int i = 0; i < _face->num_charmaps; i++) {
-      pnmtext_cat.debug(false) << " " << (void *)_face->charmaps[i];
+      << name << " has " << _face->get_face()->num_charmaps << " charmaps:\n";
+    for (int i = 0; i < _face->get_face()->num_charmaps; i++) {
+      pnmtext_cat.debug(false) << " " << (void *)_face->get_face()->charmaps[i];
     }
     pnmtext_cat.debug(false) << "\n";
     pnmtext_cat.debug()
-      << "default charmap is " << (void *)_face->charmap << "\n";
+      << "default charmap is " << (void *)_face->get_face()->charmap << "\n";
   }
-  if (_face->charmap == NULL) {
+  if (_face->get_face()->charmap == NULL) {
     // If for some reason FreeType didn't set us up a charmap,
     // then set it up ourselves.
-    if (_face->num_charmaps == 0) {
+    if (_face->get_face()->num_charmaps == 0) {
       pnmtext_cat.warning()
         << name << " has no charmaps available.\n";
     } else {
       pnmtext_cat.warning()
         << name << " has no default Unicode charmap.\n";
-      if (_face->num_charmaps > 1) {
+      if (_face->get_face()->num_charmaps > 1) {
         pnmtext_cat.warning()
           << "Arbitrarily choosing first of " 
-          << _face->num_charmaps << " charmaps.\n";
+          << _face->get_face()->num_charmaps << " charmaps.\n";
       }
-      FT_Set_Charmap(_face, _face->charmaps[0]);
+      FT_Set_Charmap(_face->get_face(), _face->get_face()->charmaps[0]);
     }
   }
 
@@ -320,7 +326,7 @@ reset_scale() {
   int dpi = (int)(_font_pixels_per_unit * units_per_inch);
   
   _font_pixel_size = 0;
-  int error = FT_Set_Char_Size(_face,
+  int error = FT_Set_Char_Size(_face->get_face(),
                                (int)(_point_size * 64), (int)(_point_size * 64),
                                dpi, dpi);
   if (error) {
@@ -331,16 +337,16 @@ reset_scale() {
     int desired_height = (int)(_font_pixels_per_unit * _point_size / _points_per_unit + 0.5f);
     int best_size = -1;
     int largest_size = -1;
-    if (_face->num_fixed_sizes > 0) {
+    if (_face->get_face()->num_fixed_sizes > 0) {
       largest_size = 0;
       int best_diff = 0;
-      for (int i = 0; i < _face->num_fixed_sizes; i++) {
-        int diff = _face->available_sizes[i].height - desired_height;
+      for (int i = 0; i < _face->get_face()->num_fixed_sizes; i++) {
+        int diff = _face->get_face()->available_sizes[i].height - desired_height;
         if (diff > 0 && (best_size == -1 || diff < best_diff)) {
           best_size = i;
           best_diff = diff;
         }
-        if (_face->available_sizes[i].height > _face->available_sizes[largest_size].height) {
+        if (_face->get_face()->available_sizes[i].height > _face->get_face()->available_sizes[largest_size].height) {
           largest_size = i;
         }
       }
@@ -350,9 +356,9 @@ reset_scale() {
     }
 
     if (best_size >= 0) {
-      int pixel_height = _face->available_sizes[best_size].height;
-      int pixel_width = _face->available_sizes[best_size].width;
-      error = FT_Set_Pixel_Sizes(_face, pixel_width, pixel_height);
+      int pixel_height = _face->get_face()->available_sizes[best_size].height;
+      int pixel_width = _face->get_face()->available_sizes[best_size].width;
+      error = FT_Set_Pixel_Sizes(_face->get_face(), pixel_width, pixel_height);
       if (!error) {
         _font_pixels_per_unit = pixel_height * _points_per_unit / _point_size;
         _scale_factor = _font_pixels_per_unit / _tex_pixels_per_unit;
@@ -375,16 +381,16 @@ reset_scale() {
     return false;
   }
 
-  _line_height = _face->size->metrics.height / (_font_pixels_per_unit * 64.0f);
+  _line_height = _face->get_face()->size->metrics.height / (_font_pixels_per_unit * 64.0f);
 
   // Determine the correct width for a space.
-  error = FT_Load_Char(_face, ' ', FT_LOAD_DEFAULT);
+  error = FT_Load_Char(_face->get_face(), ' ', FT_LOAD_DEFAULT);
   if (error) {
     // Space isn't defined.  Oh well.
     _space_advance = 0.25f * _line_height;
 
   } else {
-    _space_advance = _face->glyph->advance.x / (_font_pixels_per_unit * 64.0f);
+    _space_advance = _face->get_face()->glyph->advance.x / (_font_pixels_per_unit * 64.0f);
   }
 
   return true;

+ 2 - 1
panda/src/pnmtext/freetypeFont.h

@@ -25,6 +25,7 @@
 #include "pmap.h"
 #include "pnmImage.h"
 #include "namable.h"
+#include "freetypeFace.h"
 
 #include <ft2build.h>
 #include FT_FREETYPE_H
@@ -93,7 +94,7 @@ protected:
   float _line_height;
   float _space_advance;
 
-  FT_Face _face;
+  PT(FreetypeFace) _face;
 
 protected:
   bool _font_loaded;

+ 2 - 2
panda/src/pnmtext/pnmTextMaker.cxx

@@ -111,7 +111,7 @@ generate_into(const wstring &text, PNMImage &dest_image, int x, int y) {
 ////////////////////////////////////////////////////////////////////
 PNMTextGlyph *PNMTextMaker::
 get_glyph(int character) {
-  int glyph_index = FT_Get_Char_Index(_face, character);
+  int glyph_index = FT_Get_Char_Index(_face->get_face(), character);
 
   Glyphs::iterator gi;
   gi = _glyphs.find(glyph_index);
@@ -150,7 +150,7 @@ make_glyph(int glyph_index) {
     return (PNMTextGlyph *)NULL;
   }
 
-  FT_GlyphSlot slot = _face->glyph;
+  FT_GlyphSlot slot = _face->get_face()->glyph;
   FT_Bitmap &bitmap = slot->bitmap;
 
   double advance = slot->advance.x / 64.0;

+ 1 - 0
panda/src/pnmtext/pnmtext_composite1.cxx

@@ -1,4 +1,5 @@
 #include "config_pnmtext.cxx"
+#include "freetypeFace.cxx"
 #include "freetypeFont.cxx"
 #include "pnmTextGlyph.cxx"
 #include "pnmTextMaker.cxx"

+ 16 - 6
panda/src/putil/string_utils.cxx

@@ -176,15 +176,20 @@ extract_words(const wstring &str, pvector<wstring> &words) {
 //               vector.
 ////////////////////////////////////////////////////////////////////
 void
-tokenize(const string &str, vector_string &words, const string &delimiters) {
+tokenize(const string &str, vector_string &words, const string &delimiters,
+         bool discard_repeated_delimiters) {
   size_t p = 0;
   while (p < str.length()) {
     size_t q = str.find_first_of(delimiters, p);
     if (q == string::npos) {
-      words.push_back(str.substr(p));
+      if (q - p || !discard_repeated_delimiters){
+        words.push_back(str.substr(p));
+      }
       return;
     }
-    words.push_back(str.substr(p, q - p));
+    if (q - p || !discard_repeated_delimiters){
+        words.push_back(str.substr(p, q - p));
+    }
     p = q + 1;
   }
   words.push_back(string());
@@ -203,15 +208,20 @@ tokenize(const string &str, vector_string &words, const string &delimiters) {
 //               vector.
 ////////////////////////////////////////////////////////////////////
 void
-tokenize(const wstring &str, pvector<wstring> &words, const wstring &delimiters) {
+tokenize(const wstring &str, pvector<wstring> &words, const wstring &delimiters,
+         bool discard_repeated_delimiters) {
   size_t p = 0;
   while (p < str.length()) {
     size_t q = str.find_first_of(delimiters, p);
     if (q == string::npos) {
-      words.push_back(str.substr(p));
+      if (q - p || !discard_repeated_delimiters){
+        words.push_back(str.substr(p));
+      }
       return;
     }
-    words.push_back(str.substr(p, q - p));
+    if (q - p || !discard_repeated_delimiters){
+      words.push_back(str.substr(p, q - p));
+    }
     p = q + 1;
   }
   words.push_back(wstring());

+ 4 - 2
panda/src/putil/string_utils.h

@@ -39,9 +39,11 @@ EXPCL_PANDA_PUTIL int extract_words(const wstring &str, pvector<wstring> &words)
 
 // Separates the string into words according to the indicated delimiters.
 EXPCL_PANDA_PUTIL void tokenize(const string &str, vector_string &words,
-                          const string &delimiters);
+                          const string &delimiters,
+                          bool discard_repeated_delimiters = false);
 EXPCL_PANDA_PUTIL void tokenize(const wstring &str, pvector<wstring> &words,
-                          const wstring &delimiters);
+                          const wstring &delimiters,
+                          bool discard_repeated_delimiters = false);
 
 // Trims leading and/or trailing whitespace from the string.
 EXPCL_PANDA_PUTIL string trim_left(const string &str);

+ 5 - 5
panda/src/text/dynamicTextFont.cxx

@@ -216,8 +216,8 @@ write(ostream &out, int indent_level) const {
     indent(out, indent_level + 2) 
       << glyph_index;
 
-    if (FT_HAS_GLYPH_NAMES(_face)) {
-      int error = FT_Get_Glyph_Name(_face, glyph_index, 
+    if (FT_HAS_GLYPH_NAMES(_face->get_face())) {
+      int error = FT_Get_Glyph_Name(_face->get_face(), glyph_index, 
                                     glyph_name, max_glyph_name);
 
       // Some fonts, notably MS Mincho, claim to have glyph names but
@@ -249,7 +249,7 @@ get_glyph(int character, const TextGlyph *&glyph) {
     return false;
   }
 
-  int glyph_index = FT_Get_Char_Index(_face, character);
+  int glyph_index = FT_Get_Char_Index(_face->get_face(), character);
   if (text_cat.is_spam()) {
     text_cat.spam()
       << *this << " maps " << character << " to glyph " << glyph_index << "\n";
@@ -404,7 +404,7 @@ make_glyph(int character, int glyph_index) {
     return (DynamicTextGlyph *)NULL;
   }
 
-  FT_GlyphSlot slot = _face->glyph;
+  FT_GlyphSlot slot = _face->get_face()->glyph;
   FT_Bitmap &bitmap = slot->bitmap;
 
   if ((bitmap.width == 0 || bitmap.rows == 0) && (glyph_index == 0)) {
@@ -423,7 +423,7 @@ make_glyph(int character, int glyph_index) {
     // Re-stroke the glyph to make it an outline glyph.
     /*
     FT_Stroker stroker;
-    FT_Stroker_New(_face->memory, &stroker);
+    FT_Stroker_New(_face->get_face()->memory, &stroker);
     FT_Stroker_Set(stroker, 16 * 16, FT_STROKER_LINECAP_BUTT,
                    FT_STROKER_LINEJOIN_ROUND, 0);
 

+ 6 - 0
panda/src/windisplay/config_windisplay.cxx

@@ -56,6 +56,12 @@ ConfigVariableBool ime_hide
 ("ime-hide", false,
  PRC_DESC("Set this true to hide ime windows."));
 
+ConfigVariableBool request_dxdisplay_information
+("request-dxdisplay-information", true,
+ PRC_DESC("Setting this to false skips some display information discovery "
+          "routines that can speed up initialization when DX support is "
+          "present."));
+
 ConfigVariableBool swapbuffer_framelock
 ("swapbuffer-framelock", false,
  PRC_DESC("Set this true to enable HW swapbuffer frame-lock on 3dlabs cards"));

+ 1 - 0
panda/src/windisplay/config_windisplay.h

@@ -29,6 +29,7 @@ extern ConfigVariableBool auto_cpu_data;
 extern ConfigVariableBool ime_composition_w;
 extern ConfigVariableBool ime_aware;
 extern ConfigVariableBool ime_hide;
+extern ConfigVariableBool request_dxdisplay_information;
 
 extern EXPCL_PANDAWIN ConfigVariableBool swapbuffer_framelock;
 

+ 13 - 9
panda/src/windisplay/winGraphicsPipe.cxx

@@ -820,20 +820,24 @@ WinGraphicsPipe() {
   }
 
 #ifdef HAVE_DX9
-  DisplaySearchParameters display_search_parameters_dx9;
-  int dx9_display_information (DisplaySearchParameters &display_search_parameters_dx9, DisplayInformation *display_information);
+  if (request_dxdisplay_information){
+    DisplaySearchParameters display_search_parameters_dx9;
+    int dx9_display_information (DisplaySearchParameters &display_search_parameters_dx9, DisplayInformation *display_information);
 
-  if (state == false && dx9_display_information (display_search_parameters_dx9, _display_information)) {
-    state = true;
+    if (state == false && dx9_display_information (display_search_parameters_dx9, _display_information)) {
+      state = true;
+    }
   }
 #endif
 
 #ifdef HAVE_DX8
-  DisplaySearchParameters display_search_parameters_dx8;
-  int dx8_display_information (DisplaySearchParameters &display_search_parameters_dx8, DisplayInformation *display_information);
-  
-  if (state == false && dx8_display_information (display_search_parameters_dx8, _display_information)) {
-    state = true;    
+  if (request_dxdisplay_information){
+    DisplaySearchParameters display_search_parameters_dx8;
+    int dx8_display_information (DisplaySearchParameters &display_search_parameters_dx8, DisplayInformation *display_information);
+    
+    if (state == false && dx8_display_information (display_search_parameters_dx8, _display_information)) {
+      state = true;    
+    }
   }
 #endif