Crash getting text width when maximizing with D3D Driver
jmasterx

I am not sure how I can reproduce this in a minimum example, but, my code ran fine in 5.1.5 but with 5.1.6, it crashes when I maximize while getting the text width with a null pointer exception.

It is during the caching of a glyph.

{"name":"607536","src":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/1\/1\/119a0d74e0b5bc6b8a85b1d9d6cc174d.png","w":1040,"h":602,"tn":"\/\/djungxnpq2nug.cloudfront.net\/image\/cache\/1\/1\/119a0d74e0b5bc6b8a85b1d9d6cc174d"}607536

This happens here:

    glyph_data = alloc_glyph_region(font_data, ft_index,
       w + 2, h + 2, false, glyph, lock_more);

Then here:

      cache_glyph(data, face, ft_index, glyph, true);

Then here:

   return f->vtable->text_length(f, ustr);

Then here:

  int Allegro5Font::getTextWidth( const std::string &text ) const
  {
    if(font)
    {
      return al_get_text_width(font,text.c_str());
    }

    return 0;
    
  }

Then here:

  void Label::resizeToContents()
  {
    double computedWidth = getFont()->getTextWidth(getText()) + getMargin(SIDE_LEFT) + getMargin(SIDE_RIGHT);
    if (this->getMaxSize().getWidth() > computedWidth)
      computedWidth = this->getMaxSize().getWidth();
    _setSizeInternal(Dimension(int(computedWidth), getFont()->getLineHeight() * getNumTextLines() + getMargin(SIDE_TOP) + getMargin(SIDE_BOTTOM)));
  }

Then here:

  void Label::setFont( const Font *font )
  {
    Widget::setFont(font);
    if(isAutosizing())
    {
      resizeToContents();
    }
    updateLabel();
  }

Then here:

  void GameInformation::resize( int w, int h )
  {
    float ctrl = 0.75f;
    float scale = getProportions()->getScale();
    if(scale > 0.75f)
    {
      scale = 0.75f;
    }

    m_tableLabel->setFont(m_font->getFont(scale * 2.4f * ctrl));
    m_tableLabel->resizeToContents();
...

Then here:

  void GameScene::resizeEvent( int width, int height )
  {
    m_proportions.resize(width,height);

    //resize the elements
    for(size_t i = 0; i < m_dynamicElements.size();++i)
    {
      m_dynamicElements[i]->resize(width,height);
    }
  }

Then here:

  void SceneManager::sendResizeMessage( int w, int h )
  {
    al_acknowledge_resize(m_devices->getDisplay()->getContext());
    m_g.resizeBuffer(w,h);
    m_currentScene->processGuiResizeEvent();
    m_currentScene->resizeEvent(
      w,h);
    Log::write("Scene Manager","Resize Event: Width:" +  StringUtil::toString(w) + 
      " Height:" + StringUtil::toString(h));
  }

Then here:

#SelectExpand
1 void SceneManager::defaultBeginEventHandler( ALLEGRO_EVENT*evt ) 2 { 3 4 m_currentScene->processGuiInputEvent(evt); 5 6 if(evt->type == ALLEGRO_EVENT_TIMER && evt->timer.source == m_gameTimer) 7 { 8 m_needsRedraw = true; 9 m_currentScene->processGuiLogic(); 10 m_devices->getNetClient()->tick(); 11 } 12 else if(evt->type == ALLEGRO_EVENT_DISPLAY_RESIZE) 13 { 14 sendResizeMessage(evt->display.width,evt->display.height); 15 } 16 }

Then here:

#SelectExpand
1 void SceneManager::run() 2 { 3 m_devices->setSceneMessenger(this); 4 5 al_start_timer(m_gameTimer); 6 7 //is the event handled? 8 bool handled = false; 9 ALLEGRO_EVENT next; 10 int numTicks = 0; 11 12 //main loop 13 while(m_gameIsRunning) 14 { 15 16 handled = false; 17 al_wait_for_event(queue,&evt); 18 19 bool hasNext = al_peek_next_event(queue,&next); 20 if(hasNext && next.type == ALLEGRO_EVENT_TIMER) 21 { 22 al_drop_next_event(queue); 23 } 24 //render the scene 25 if(m_needsRedraw && al_is_event_queue_empty(queue)) 26 { 27 m_g.begin(); 28 m_currentScene->render(); 29 m_g.end(); 30 31 m_needsRedraw = false; 32 } 33 34 defaultBeginEventHandler(&evt); 35 m_currentScene->processEvent(&evt,handled); 36 37 //do default behavior if event was not handled by the scene 38 if (!handled) 39 { 40 defaultEndEventHandler(&evt); 41 } 42 43 processMessages(); 44 } 45 }

Then problem seems to be that:
ptr = data->page_lr->data;

page_lr is NULL.

Probably the lock fails:

      data->page_lr = al_lock_bitmap_region(page,
         data->lock_rect.x, data->lock_rect.y,
         data->lock_rect.w, data->lock_rect.h,
         ALLEGRO_PIXEL_FORMAT_ABGR_8888_LE, ALLEGRO_LOCK_WRITEONLY);

I do not know why, but the logs have this to say:

d3d      D          d3d_bmp.cpp:492  _al_d3d_sync_bitmap              [  10.12205] _al_d3d_sync_bitmap (video) ref count == 1
d3d      W         d3d_disp.cpp:1094 _al_d3d_reset_device             [  11.84075] Reset failed
d3d      E         d3d_disp.cpp:2460 d3d_set_target_bitmap            [  11.84119] d3d_set_target_bitmap: Unable to set render target to texture surface.
d3d      E         d3d_disp.cpp:2460 d3d_set_target_bitmap            [  11.84122] d3d_set_target_bitmap: Unable to set render target to texture surface.
font     D                ttf.c:216  alloc_glyph_region               [  11.85194] Glyph 55: 15x16 (16x16)
d3d      E          d3d_bmp.cpp:453  _al_d3d_sync_bitmap              [  11.85197] A texture is null.

I am starting to wonder if I just should switch to OpenGL exclusively. I love the idea of D3D, but when it loses the device, it has created so many bugs for me over time.

If I have time I will try to make a minimum example.

Thanks

Thread #612544. Printed from Allegro.cc