summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJesse Barnes <jbarnes@virtuousgeek.org>2008-09-30 12:54:27 -0700
committerJesse Barnes <jbarnes@virtuousgeek.org>2008-09-30 12:54:27 -0700
commit1eb46d055b147941fa529ac582c336a114f47892 (patch)
tree21dab3fcfe9b95e4f99322029bb76a99b303f3f9
parent8408995ffbf705aa0bc09ab72c58c2e31a4b70c3 (diff)
parent497b7420c4a76df553ed53322a390a1c754ce30c (diff)
Merge branch 'master' into xf86-video-intel-2.5-branch
-rw-r--r--configure.ac2
-rw-r--r--man/intel.man8
-rw-r--r--src/bios_reader/bios_reader.c157
-rw-r--r--src/i810_reg.h3
-rw-r--r--src/i830.h4
-rw-r--r--src/i830_bios.c13
-rw-r--r--src/i830_crt.c11
-rw-r--r--src/i830_display.c48
-rw-r--r--src/i830_driver.c34
-rw-r--r--src/i830_video.c2
-rw-r--r--uxa/uxa-glyphs.c4
11 files changed, 208 insertions, 78 deletions
diff --git a/configure.ac b/configure.ac
index 86bb80fd..1aa44f55 100644
--- a/configure.ac
+++ b/configure.ac
@@ -203,7 +203,7 @@ dnl Use lots of warning flags with GCC
WARN_CFLAGS=""
if test "x$GCC" = "xyes"; then
- WARN_CFLAGS="-Wall -Wpointer-arith -Wstrict-prototypes \
+ WARN_CFLAGS="-Wall -Werror -Wpointer-arith -Wstrict-prototypes \
-Wmissing-prototypes -Wmissing-declarations \
-Wnested-externs -fno-strict-aliasing"
fi
diff --git a/man/intel.man b/man/intel.man
index 6969a159..115b35ac 100644
--- a/man/intel.man
+++ b/man/intel.man
@@ -25,7 +25,7 @@ the 830M and later.
.B intel
supports the i810, i810-DC100, i810e, i815, i830M, 845G, 852GM, 855GM,
865G, 915G, 915GM, 945G, 945GM, 965G, 965Q, 946GZ, 965GM, 945GME,
-G33, Q33, and Q35 chipsets.
+G33, Q33, Q35, G35, GM45, G45, Q45, G43 and G41 chipsets.
.SH CONFIGURATION DETAILS
Please refer to __xconfigfile__(__filemansuffix__) for general configuration
@@ -222,6 +222,12 @@ information.
Enable XvMC driver. Current support MPEG2 MC on 915/945 and G33 series.
User should provide absolute path to libIntelXvMC.so in XvMCConfig file.
Default: Disabled.
+.TP
+.BI "Option \*qForceSDVODetect\*q \*q" boolean \*q
+Instead of depending on SDVO detect status bit to initialize SDVO outputs,
+this option trys to ignore that status bit and try to probe on all SDVO
+ports anyway. Try this if some output is not detected on your ADD2 card.
+Use of this option will slow down your startup time. Default: Disabled.
.SH OUTPUT CONFIGURATION
On 830M and better chipsets, the driver supports runtime configuration of
diff --git a/src/bios_reader/bios_reader.c b/src/bios_reader/bios_reader.c
index 9e053170..29c3edb0 100644
--- a/src/bios_reader/bios_reader.c
+++ b/src/bios_reader/bios_reader.c
@@ -59,42 +59,66 @@ struct _fake_i830 *pI830 = &I830;
#define YESNO(val) ((val) ? "yes" : "no")
+struct bdb_block {
+ uint8_t id;
+ uint16_t size;
+ void *data;
+};
+
+struct bdb_header *bdb;
static int tv_present;
static int lvds_present;
static int panel_type;
-static void *find_section(struct bdb_header *bdb, int section_id)
+static struct bdb_block *find_section(int section_id)
{
- unsigned char *base = (unsigned char *)bdb;
- int index = 0;
- uint16_t total, current_size;
- unsigned char current_id;
-
- /* skip to first section */
- index += bdb->header_size;
- total = bdb->bdb_size;
-
- /* walk the sections looking for section_id */
- while (index < total) {
- current_id = *(base + index);
- index++;
- current_size = *((uint16_t *)(base + index));
- index += 2;
- if (current_id == section_id)
- return base + index;
- index += current_size;
+ struct bdb_block *block;
+ unsigned char *base = (unsigned char *)bdb;
+ int index = 0;
+ uint16_t total, current_size;
+ unsigned char current_id;
+
+ /* skip to first section */
+ index += bdb->header_size;
+ total = bdb->bdb_size;
+
+ block = malloc(sizeof(*block));
+ if (!block) {
+ fprintf(stderr, "out of memory\n");
+ exit(-1);
+ }
+
+ /* walk the sections looking for section_id */
+ while (index < total) {
+ current_id = *(base + index);
+ index++;
+ current_size = *((uint16_t *)(base + index));
+ index += 2;
+ if (current_id == section_id) {
+ block->id = current_id;
+ block->size = current_size;
+ block->data = base + index;
+ return block;
}
+ index += current_size;
+ }
- return NULL;
+ free(block);
+ return NULL;
}
-static void dump_general_features(void *data)
+static void dump_general_features(void)
{
- struct bdb_general_features *features = data;
+ struct bdb_general_features *features;
+ struct bdb_block *block;
+
+ block = find_section(BDB_GENERAL_FEATURES);
- if (!data)
+ if (!block)
return;
+ features = block->data;
+
printf("General features block:\n");
printf("\tPanel fitting: ");
@@ -133,16 +157,24 @@ static void dump_general_features(void *data)
tv_present = 1; /* should be based on whether TV DAC exists */
lvds_present = 1; /* should be based on IS_MOBILE() */
+
+ free(block);
}
-static void dump_general_definitions(void *data)
+static void dump_general_definitions(void)
{
- struct bdb_general_definitions *defs = data;
- unsigned char *lvds_data = defs->tv_or_lvds_info;
+ struct bdb_block *block;
+ struct bdb_general_definitions *defs;
+ unsigned char *lvds_data;
+
+ block = find_section(BDB_GENERAL_DEFINITIONS);
- if (!data)
+ if (!block)
return;
+ defs = block->data;
+ lvds_data = defs->tv_or_lvds_info;
+
printf("General definitions block:\n");
printf("\tCRT DDC GMBUS addr: 0x%02x\n", defs->crt_ddc_gmbus_pin);
@@ -157,15 +189,22 @@ static void dump_general_definitions(void *data)
lvds_data += 33;
if (lvds_present)
printf("\tLFP DDC GMBUS addr: 0x%02x\n", lvds_data[19]);
+
+ free(block);
}
-static void dump_lvds_options(void *data)
+static void dump_lvds_options(void)
{
- struct bdb_lvds_options *options = data;
+ struct bdb_block *block;
+ struct bdb_lvds_options *options;
+
+ block = find_section(BDB_LVDS_OPTIONS);
- if (!data)
+ if (!block)
return;
+ options = block->data;
+
printf("LVDS options block:\n");
panel_type = options->panel_type;
@@ -178,19 +217,51 @@ static void dump_lvds_options(void *data)
printf("\tPFIT enhanced text mode: %s\n",
YESNO(options->pfit_text_mode_enhanced));
printf("\tPFIT mode: %d\n", options->pfit_mode);
+
+ free(block);
}
-static void dump_lvds_data(void *data, unsigned char *base)
+static void dump_lvds_ptr_data(void)
{
- struct bdb_lvds_lfp_data *lvds_data = data;
+ struct bdb_block *block;
+ struct bdb_lvds_lfp_data_ptrs *ptrs;
+ struct lvds_fp_timing *fp_timing;
+
+ block = find_section(BDB_LVDS_LFP_DATA_PTRS);
+ if (!block)
+ return;
+
+ ptrs = block->data;
+ fp_timing = (struct lvds_fp_timing *)((uint8_t *)bdb +
+ ptrs->ptr[panel_type].fp_timing_offset);
+
+ printf("LVDS timing pointer data:\n");
+ printf(" Number of entries: %d\n", ptrs->lvds_entries);
+
+ printf("\tpanel type %02i: %dx%d\n", panel_type, fp_timing->x_res,
+ fp_timing->y_res);
+
+ free(block);
+}
+
+static void dump_lvds_data(void)
+{
+ struct bdb_block *block;
+ struct bdb_lvds_lfp_data *lvds_data;
+ int num_entries;
int i;
- if (!data)
+ block = find_section(BDB_LVDS_LFP_DATA);
+ if (!block)
return;
+ lvds_data = block->data;
+ num_entries = block->size / sizeof(struct bdb_lvds_lfp_data_entry);
+
printf("LVDS panel data block (preferred block marked with '*'):\n");
+ printf(" Number of entries: %d\n", num_entries);
- for (i = 0; i < 16; i++) {
+ for (i = 0; i < num_entries; i++) {
struct bdb_lvds_lfp_data_entry *lfp_data = &lvds_data->data[i];
uint8_t *timing_data = (uint8_t *)&lfp_data->dvo_timing;
char marker;
@@ -198,13 +269,13 @@ static void dump_lvds_data(void *data, unsigned char *base)
if (i == panel_type)
marker = '*';
else
- continue;
+ marker = ' ';
printf("%c\tpanel type %02i: %dx%d clock %d\n", marker,
i, lfp_data->fp_timing.x_res, lfp_data->fp_timing.y_res,
_PIXEL_CLOCK(timing_data));
printf("\t\tinfo:\n");
- printf("\t\t LVDS: 0x%08lx\n",
+ printf("\t\t LVDS: 0x%08lx\n",
(unsigned long)lfp_data->fp_timing.lvds_reg_val);
printf("\t\t PP_ON_DELAYS: 0x%08lx\n",
(unsigned long)lfp_data->fp_timing.pp_on_reg_val);
@@ -224,14 +295,13 @@ static void dump_lvds_data(void *data, unsigned char *base)
_V_SYNC_OFF(timing_data),
_V_SYNC_WIDTH(timing_data));
}
-
+ free(block);
}
int main(int argc, char **argv)
{
int fd;
struct vbt_header *vbt = NULL;
- struct bdb_header *bdb;
int vbt_off, bdb_off, i;
char *filename = "bios";
struct stat finfo;
@@ -240,7 +310,7 @@ int main(int argc, char **argv)
printf("usage: %s <rom file>\n", argv[0]);
return 1;
}
-
+
filename = argv[1];
fd = open(filename, O_RDONLY);
@@ -281,10 +351,11 @@ int main(int argc, char **argv)
printf("BDB sig: %16s\n", bdb->signature);
printf("BDB vers: %d.%d\n", bdb->version / 100, bdb->version % 100);
- dump_general_features(find_section(bdb, BDB_GENERAL_FEATURES));
- dump_general_definitions(find_section(bdb, BDB_GENERAL_DEFINITIONS));
- dump_lvds_options(find_section(bdb, BDB_LVDS_OPTIONS));
- dump_lvds_data(find_section(bdb, BDB_LVDS_LFP_DATA), (unsigned char *)bdb);
+ dump_general_features();
+ dump_general_definitions();
+ dump_lvds_options();
+ dump_lvds_data();
+ dump_lvds_ptr_data();
return 0;
}
diff --git a/src/i810_reg.h b/src/i810_reg.h
index 5b90e12e..6458008c 100644
--- a/src/i810_reg.h
+++ b/src/i810_reg.h
@@ -1167,6 +1167,9 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
# define I965_DM_CLOCK_GATE_DISABLE (1 << 0)
#define RENCLK_GATE_D2 0x6208
+#define VF_UNIT_CLOCK_GATE_DISABLE (1 << 9)
+#define GS_UNIT_CLOCK_GATE_DISABLE (1 << 7)
+#define CL_UNIT_CLOCK_GATE_DISABLE (1 << 6)
#define RAMCLK_GATE_D 0x6210 /* CRL only */
#define DEUC 0x6214 /* CRL only */
diff --git a/src/i830.h b/src/i830.h
index 5fb7e24b..491dfd00 100644
--- a/src/i830.h
+++ b/src/i830.h
@@ -714,6 +714,10 @@ typedef struct _I830Rec {
/** Enables logging of debug output related to mode switching. */
Bool debug_modes;
unsigned int quirk_flag;
+
+ /* User option to ignore SDVO detect bit status, in case some outputs
+ not detected on SDVO, so let driver try its best. */
+ Bool force_sdvo_detect;
} I830Rec;
#define I830PTR(p) ((I830Ptr)((p)->driverPrivate))
diff --git a/src/i830_bios.c b/src/i830_bios.c
index ff49025d..2cb0b07b 100644
--- a/src/i830_bios.c
+++ b/src/i830_bios.c
@@ -88,8 +88,8 @@ static void
parse_panel_data(I830Ptr pI830, struct bdb_header *bdb)
{
struct bdb_lvds_options *lvds_options;
- struct bdb_lvds_lfp_data *lvds_lfp_data;
- struct bdb_lvds_lfp_data_entry *entry;
+ struct bdb_lvds_lfp_data_ptrs *lvds_lfp_data_ptrs;
+ int timing_offset;
DisplayModePtr fixed_mode;
unsigned char *timing_ptr;
@@ -104,12 +104,13 @@ parse_panel_data(I830Ptr pI830, struct bdb_header *bdb)
if (lvds_options->panel_type == 0xff)
return;
- lvds_lfp_data = find_section(bdb, BDB_LVDS_LFP_DATA);
- if (!lvds_lfp_data)
+ lvds_lfp_data_ptrs = find_section(bdb, BDB_LVDS_LFP_DATA_PTRS);
+ if (!lvds_lfp_data_ptrs)
return;
- entry = &lvds_lfp_data->data[lvds_options->panel_type];
- timing_ptr = (unsigned char *)&entry->dvo_timing;
+ timing_offset =
+ lvds_lfp_data_ptrs->ptr[lvds_options->panel_type].dvo_timing_offset;
+ timing_ptr = (unsigned char *)bdb + timing_offset;
fixed_mode = xnfalloc(sizeof(DisplayModeRec));
memset(fixed_mode, 0, sizeof(*fixed_mode));
diff --git a/src/i830_crt.c b/src/i830_crt.c
index 5812e2b7..2e70eb8d 100644
--- a/src/i830_crt.c
+++ b/src/i830_crt.c
@@ -161,6 +161,14 @@ i830_crt_detect_hotplug(xf86OutputPtr output)
uint32_t temp;
const int timeout_ms = 1000;
int starttime, curtime;
+ int tries = 1;
+
+ /* On 4 series, CRT detect sequence need to be done twice for safe. */
+ if (IS_G4X(pI830))
+ tries = 2;
+
+retry:
+ tries--;
temp = INREG(PORT_HOTPLUG_EN);
@@ -173,6 +181,9 @@ i830_crt_detect_hotplug(xf86OutputPtr output)
break;
}
+ if (tries > 0)
+ goto retry;
+
if ((INREG(PORT_HOTPLUG_STAT) & CRT_HOTPLUG_MONITOR_MASK) ==
CRT_HOTPLUG_MONITOR_COLOR)
{
diff --git a/src/i830_display.c b/src/i830_display.c
index ed49fb0e..0632f3a3 100644
--- a/src/i830_display.c
+++ b/src/i830_display.c
@@ -857,27 +857,31 @@ i830_crtc_dpms(xf86CrtcPtr crtc, int mode)
/* Give the overlay scaler a chance to disable if it's on this pipe */
i830_crtc_dpms_video(crtc, FALSE);
- /* Disable the VGA plane that we never use */
- OUTREG(VGACNTRL, VGA_DISP_DISABLE);
+ /*
+ * The documentation says :
+ * - Disable planes (VGA or hires)
+ * - Disable pipe
+ * - Disable VGA display
+ */
- /* May need to leave pipe A on */
- if ((pipe != 0) || !(pI830->quirk_flag & QUIRK_PIPEA_FORCE))
+ /* Disable display plane */
+ temp = INREG(dspcntr_reg);
+ if ((temp & DISPLAY_PLANE_ENABLE) != 0)
{
- /* Disable display plane */
- temp = INREG(dspcntr_reg);
- if ((temp & DISPLAY_PLANE_ENABLE) != 0)
- {
- OUTREG(dspcntr_reg, temp & ~DISPLAY_PLANE_ENABLE);
- /* Flush the plane changes */
- OUTREG(dspbase_reg, INREG(dspbase_reg));
- POSTING_READ(dspbase_reg);
- }
+ OUTREG(dspcntr_reg, temp & ~DISPLAY_PLANE_ENABLE);
+ /* Flush the plane changes */
+ OUTREG(dspbase_reg, INREG(dspbase_reg));
+ POSTING_READ(dspbase_reg);
+ }
- if (!IS_I9XX(pI830)) {
- /* Wait for vblank for the disable to take effect */
- i830WaitForVblank(pScrn);
- }
+ if (!IS_I9XX(pI830)) {
+ /* Wait for vblank for the disable to take effect */
+ i830WaitForVblank(pScrn);
+ }
+ /* May need to leave pipe A on */
+ if ((pipe != 0) || !(pI830->quirk_flag & QUIRK_PIPEA_FORCE))
+ {
/* Next, disable display pipes */
temp = INREG(pipeconf_reg);
if ((temp & PIPEACONF_ENABLE) != 0) {
@@ -893,9 +897,15 @@ i830_crtc_dpms(xf86CrtcPtr crtc, int mode)
OUTREG(dpll_reg, temp & ~DPLL_VCO_ENABLE);
POSTING_READ(dpll_reg);
}
+
+ /* Wait for the clocks to turn off. */
+ usleep(150);
}
- /* Wait for the clocks to turn off. */
- usleep(150);
+
+ /* Disable the VGA plane that we never use. */
+ OUTREG(VGACNTRL, VGA_DISP_DISABLE);
+ i830WaitForVblank(pScrn);
+
break;
}
diff --git a/src/i830_driver.c b/src/i830_driver.c
index 9bf0a64f..53219c39 100644
--- a/src/i830_driver.c
+++ b/src/i830_driver.c
@@ -316,6 +316,7 @@ typedef enum {
#ifdef INTEL_XVMC
OPTION_XVMC,
#endif
+ OPTION_FORCE_SDVO_DETECT,
} I830Opts;
static OptionInfoRec I830Options[] = {
@@ -342,6 +343,7 @@ static OptionInfoRec I830Options[] = {
#ifdef INTEL_XVMC
{OPTION_XVMC, "XvMC", OPTV_BOOLEAN, {0}, TRUE},
#endif
+ {OPTION_FORCE_SDVO_DETECT, "ForceSDVODetect", OPTV_BOOLEAN, {0}, FALSE},
{-1, NULL, OPTV_NONE, {0}, FALSE}
};
/* *INDENT-ON* */
@@ -915,14 +917,14 @@ I830SetupOutputs(ScrnInfoPtr pScrn)
i830_lvds_init(pScrn);
if (IS_I9XX(pI830)) {
- if (INREG(SDVOB) & SDVO_DETECTED) {
+ if ((INREG(SDVOB) & SDVO_DETECTED) || pI830->force_sdvo_detect) {
Bool found = i830_sdvo_init(pScrn, SDVOB);
if (!found && SUPPORTS_INTEGRATED_HDMI(pI830))
i830_hdmi_init(pScrn, SDVOB);
}
- if (INREG(SDVOC) & SDVO_DETECTED) {
+ if ((INREG(SDVOC) & SDVO_DETECTED) || pI830->force_sdvo_detect) {
Bool found = i830_sdvo_init(pScrn, SDVOC);
if (!found && SUPPORTS_INTEGRATED_HDMI(pI830))
@@ -965,12 +967,18 @@ i830_init_clock_gating(ScrnInfoPtr pScrn)
/* Disable clock gating reported to work incorrectly according to the specs.
*/
if (IS_GM45(pI830) || IS_G4X(pI830)) {
+ uint32_t dspclk_gate;
OUTREG(RENCLK_GATE_D1, 0);
- OUTREG(RENCLK_GATE_D2, 0);
+ OUTREG(RENCLK_GATE_D2, VF_UNIT_CLOCK_GATE_DISABLE |
+ GS_UNIT_CLOCK_GATE_DISABLE |
+ CL_UNIT_CLOCK_GATE_DISABLE);
OUTREG(RAMCLK_GATE_D, 0);
- OUTREG(DSPCLK_GATE_D, VRHUNIT_CLOCK_GATE_DISABLE |
- OVRUNIT_CLOCK_GATE_DISABLE |
- OVCUNIT_CLOCK_GATE_DISABLE);
+ dspclk_gate = VRHUNIT_CLOCK_GATE_DISABLE |
+ OVRUNIT_CLOCK_GATE_DISABLE |
+ OVCUNIT_CLOCK_GATE_DISABLE;
+ if (IS_GM45(pI830))
+ dspclk_gate |= DSSUNIT_CLOCK_GATE_DISABLE;
+ OUTREG(DSPCLK_GATE_D, dspclk_gate);
} else if (IS_I965GM(pI830)) {
OUTREG(RENCLK_GATE_D1, I965_RCC_CLOCK_GATE_DISABLE);
OUTREG(RENCLK_GATE_D2, 0);
@@ -1458,6 +1466,12 @@ I830GetEarlyOptions(ScrnInfoPtr pScrn)
if (xf86ReturnOptValBool(pI830->Options, OPTION_FORCEENABLEPIPEA, FALSE))
pI830->quirk_flag |= QUIRK_PIPEA_FORCE;
+ if (xf86ReturnOptValBool(pI830->Options, OPTION_FORCE_SDVO_DETECT, FALSE)) {
+ pI830->force_sdvo_detect = TRUE;
+ } else {
+ pI830->force_sdvo_detect = FALSE;
+ }
+
return TRUE;
}
@@ -2359,12 +2373,15 @@ RestoreHWState(ScrnInfoPtr pScrn)
/* If the pipe A PLL is active, we can restore the pipe & plane config */
if (pI830->saveDPLL_A & DPLL_VCO_ENABLE)
{
+ OUTREG(FPA0, pI830->saveFPA0);
OUTREG(DPLL_A, pI830->saveDPLL_A & ~DPLL_VCO_ENABLE);
+ POSTING_READ(DPLL_A);
usleep(150);
}
OUTREG(FPA0, pI830->saveFPA0);
OUTREG(FPA1, pI830->saveFPA1);
OUTREG(DPLL_A, pI830->saveDPLL_A);
+ POSTING_READ(DPLL_A);
i830_dpll_settle();
if (IS_I965G(pI830))
OUTREG(DPLL_A_MD, pI830->saveDPLL_A_MD);
@@ -2420,12 +2437,15 @@ RestoreHWState(ScrnInfoPtr pScrn)
/* If the pipe B PLL is active, we can restore the pipe & plane config */
if (pI830->saveDPLL_B & DPLL_VCO_ENABLE)
{
+ OUTREG(FPB0, pI830->saveFPB0);
OUTREG(DPLL_B, pI830->saveDPLL_B & ~DPLL_VCO_ENABLE);
+ POSTING_READ(DPLL_B);
usleep(150);
}
OUTREG(FPB0, pI830->saveFPB0);
OUTREG(FPB1, pI830->saveFPB1);
OUTREG(DPLL_B, pI830->saveDPLL_B);
+ POSTING_READ(DPLL_B);
i830_dpll_settle();
if (IS_I965G(pI830))
OUTREG(DPLL_B_MD, pI830->saveDPLL_B_MD);
@@ -3038,7 +3058,7 @@ static Bool
I830ScreenInit(int scrnIndex, ScreenPtr pScreen, int argc, char **argv)
{
ScrnInfoPtr pScrn;
- vgaHWPtr hwp;
+ vgaHWPtr hwp = NULL;
I830Ptr pI830;
VisualPtr visual;
I830Ptr pI8301 = NULL;
diff --git a/src/i830_video.c b/src/i830_video.c
index 6645daae..316bc61e 100644
--- a/src/i830_video.c
+++ b/src/i830_video.c
@@ -2398,7 +2398,7 @@ I830PutImage(ScrnInfoPtr pScrn,
/* fixup pointers */
#ifdef INTEL_XVMC
if (id == FOURCC_XVMC && IS_I915(pI830)) {
- pPriv->YBuf0offset = (uint32_t)((uint64_t)buf);
+ pPriv->YBuf0offset = (uint32_t)((uintptr_t)buf);
pPriv->VBuf0offset = pPriv->YBuf0offset + (dstPitch2 * height);
pPriv->UBuf0offset = pPriv->VBuf0offset + (dstPitch * height / 2);
destId = FOURCC_YV12;
diff --git a/uxa/uxa-glyphs.c b/uxa/uxa-glyphs.c
index 364fcfbc..dc518568 100644
--- a/uxa/uxa-glyphs.c
+++ b/uxa/uxa-glyphs.c
@@ -668,6 +668,10 @@ uxa_glyphs_intersect(int nlist, GlyphListPtr list, GlyphPtr *glyphs)
x = 0;
y = 0;
+ extents.x1 = 0;
+ extents.y1 = 0;
+ extents.x2 = 0;
+ extents.y2 = 0;
while (nlist--) {
x += list->xOff;
y += list->yOff;