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

This commit is contained in:
David Rose 2009-11-18 15:00:52 +00:00
parent a7b8734fdf
commit 8a64a06946
18 changed files with 257 additions and 53 deletions

View File

@ -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());

View File

@ -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

View File

@ -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;

View File

@ -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;

View File

@ -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

View File

@ -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;
}

View File

@ -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

View File

@ -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

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

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

View File

@ -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());

View File

@ -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);

View File

@ -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);

View File

@ -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"));

View File

@ -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;

View File

@ -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