It looks safe enough to create a sub bitmap on a locked parent from the function definition. All al_create_sub_bitmap does is allocate a new ALLEGRO_BITMAP and populate it with default values.
bitmap.c#SelectExpand
431/* Function: al_create_sub_bitmap
432 */
433ALLEGRO_BITMAP *al_create_sub_bitmap(ALLEGRO_BITMAP *parent,
434 int x,
int y,
int w,
int h
)
435{
436 ALLEGRO_BITMAP *bitmap
;
437
438 if (parent->parent
) {
439 x
+= parent->xofs
;
440 y
+= parent->yofs
;
441 parent
= parent->parent
;
442 }
443
444 bitmap
= al_calloc(1,
sizeof *bitmap
);
445 bitmap->vt
= parent->vt
;
446
447 /* Sub-bitmap inherits these from the parent.
448 * Leave these unchanged so they can be detected if improperly accessed
449 * directly. */
450 bitmap->_format
= 0;
451 bitmap->_flags
= 0;
452 bitmap->_display
= (ALLEGRO_DISPLAY*)0x1;
453
454 bitmap->w
= w
;
455 bitmap->h
= h
;
456 bitmap->locked
= false;
457 bitmap->cl
= bitmap->ct
= 0;
458 bitmap->cr_excl
= w
;
459 bitmap->cb_excl
= h
;
460 al_identity_transform(&bitmap->transform
);
461 al_identity_transform(&bitmap->inverse_transform
);
462 bitmap->inverse_transform_dirty
= false;
463 al_identity_transform(&bitmap->proj_transform
);
464 al_orthographic_transform
(&bitmap->proj_transform,
0,
0,
-1.
0, w, h,
1.
0);
465 bitmap->shader
= NULL
;
466 bitmap->parent
= parent
;
467 bitmap->xofs
= x
;
468 bitmap->yofs
= y
;
469 bitmap->memory
= NULL
;
470
471 bitmap->dtor_item
= _al_register_destructor
(_al_dtor_list,
"sub_bitmap", bitmap,
472 (void (*)(void *))al_destroy_bitmap);
473
474 return bitmap
;
475}
What do you need to do with the sub-bitmaps while the parent is locked? Just create them? That should be safe.