void egl_disp_callback(uint32_t cb_arg) { #ifdef BRCM_V3D_OPT return; #endif EGL_DISP_SLOT_HANDLE_T slot_handle = (EGL_DISP_SLOT_HANDLE_T)cb_arg; DISP_T *disp; uint32_t slot; if (slot_handle == EGL_DISP_SLOT_HANDLE_INVALID) { return; } disp = slot_handle_get_disp(slot_handle); slot = slot_handle_get_slot(slot_handle); if ((disp->in_use.on & (SLOTS_N - 1)) != slot) { /* the previous image has just come off the display. we want to: * - send an async message back to the client * - notify any tasks that may have been waiting for the image to come off * the display */ ++disp->in_use.asyncs; /* we notify the llat task below */ advance_pos(&disp->in_use.on, disp->in_use.n); vcos_assert((disp->in_use.on & (SLOTS_N - 1)) == slot); khrn_sync_display_returned_notify(); } if (disp->in_use.slots[slot].swap_interval != 0) { --disp->in_use.slots[slot].swap_interval; } disp->in_use.want_us = vcos_getmicrosecs(); khrn_barrier(); disp->in_use.want = true; notify_llat(disp); }
/* call from master task. caller should notify llat task if necessary */ static uint32_t post(DISP_T *disp, uint32_t win, uint32_t swap_interval) { uint32_t slot; MEM_HANDLE_T handle; /* wait for a free slot */ while ((next_pos(disp->in_use.post, disp->in_use.n) - disp->in_use.on) > SLOTS_N) { khrn_sync_master_wait(); } khrn_barrier(); /* fill it in */ slot = disp->in_use.post & (SLOTS_N - 1); /* we take a copy of the KHRN_IMAGE_T here as in the swap interval 0 case the * width/height/stride could change before we get around to putting the image * on the display */ handle = disp->in_use.images[slot & (next_power_of_2(disp->in_use.n) - 1)]; disp->in_use.slots[slot].image = *(KHRN_IMAGE_T *)mem_lock(handle); mem_unlock(handle); disp->in_use.slots[slot].win = win; disp->in_use.slots[slot].swap_interval = swap_interval; disp->in_use.slots[slot].ready = false; disp->in_use.slots[slot].skip = false; disp->in_use.slots[slot].wait_posted = false; /* advance the post counter */ advance_pos(&disp->in_use.post, disp->in_use.n); return slot; }
static GList * tokenize (TextgenTemplate *tpl, const gchar *text, gint length, GError **error) { gboolean success = TRUE; GList *list = NULL; gint pos = 0; gint cur_line = 1; gint cur_column = 1; gint text_start = 0; GError *tmp_error = NULL; while (pos < length) { Token *instruction_token; gboolean ignore_empty_line; gint after_instruction_end; instruction_token = maybe_parse_instruction (tpl, text, length, pos, cur_line, cur_column, &ignore_empty_line, &after_instruction_end, &cur_line, &cur_column, &tmp_error); if (tmp_error) { g_propagate_error (error, tmp_error); success = FALSE; goto finish; } if (instruction_token) { gint after_text_end = pos; gint next_text_start = after_instruction_end; if (ignore_empty_line) { gint i; gint newline_before_empty_line; gint newline_after_empty_line; gboolean empty_before; gboolean empty_after; empty_before = check_line_empty_before (text, after_text_end - 1, &newline_before_empty_line); empty_after = check_line_empty_after (text, length, next_text_start, &newline_after_empty_line); if (empty_before && empty_after) { after_text_end = newline_before_empty_line + 1; next_text_start = newline_after_empty_line + 1; cur_line++; cur_column = 1; } } if (text_start < after_text_end) { Token *text_token = token_new_text_from_range (text, text_start, after_text_end); list = g_list_prepend (list, text_token); } pos = text_start = next_text_start; list = g_list_prepend (list, instruction_token); } else { advance_pos (tpl, text, length, &pos, &cur_line, &cur_column, &tmp_error); if (tmp_error) { g_propagate_error (error, tmp_error); success = FALSE; goto finish; } } } if (text_start < length) { Token *text_token = token_new_text_from_range (text, text_start, length); list = g_list_prepend (list, text_token); } finish: if (success) return g_list_reverse (list); else { g_list_free_full (list, free_token); return NULL; } }
static Token * maybe_parse_instruction (TextgenTemplate *tpl, const gchar *text, gint length, gint start, gint start_line, gint start_column, gboolean *ignore_empty_line, gint *after_end, gint *after_end_line, gint *after_end_column, GError **error) { gboolean success = TRUE; gboolean found_end = FALSE; gchar instr; gint content_offset; gchar *command = NULL; gchar *content = NULL; gint content_length; gint pos = start; gint cur_line = start_line; gint cur_column = start_column; GError *tmp_error = NULL; if (start < length - 1 && text[start] == '[') { if (text[start + 1] == '!') { *ignore_empty_line = TRUE; instr = text[start + 2]; content_offset = 3; } else { *ignore_empty_line = FALSE; instr = text[start + 1]; content_offset = 2; } if (!IS_VALID_INSTRUCTION_CHAR (instr)) return NULL; } else return NULL; pos += content_offset; cur_column += content_offset; while (pos < length) { if (pos < length - 1 && text[pos] == instr && text[pos + 1] == ']') { gint content_start = start + content_offset; content_length = pos - content_start; content = g_strndup (text + content_start, content_length); *after_end = pos + 2; cur_column += 2; found_end = TRUE; break; } advance_pos (tpl, text, length, &pos, &cur_line, &cur_column, &tmp_error); if (tmp_error) { g_propagate_error (error, tmp_error); success = FALSE; goto finish; } } if (!found_end) { emit_message (tpl, TEXTGEN_MESSAGE_ERROR, start_line, start_column, _("Could not find the end of the instruction"), instr); set_parse_error (error); success = FALSE; goto finish; } if (instr == TOKEN_COMMAND) { static GRegex *regex = NULL; GMatchInfo *match_info; gchar *old_content = content; gint start_pos; gint end_pos; if (!regex) regex = g_regex_new ("^\\s*([A-Za-z]+)\\s+(.*)$", G_REGEX_MULTILINE | G_REGEX_OPTIMIZE, 0, NULL); if (!g_regex_match (regex, old_content, 0, &match_info)) { emit_message (tpl, TEXTGEN_MESSAGE_ERROR, start_line, start_column, _("A command must look like this: [# COMMAND content #]")); set_parse_error (error); success = FALSE; goto finish; } command = g_match_info_fetch (match_info, 1); content = g_match_info_fetch (match_info, 2); g_match_info_fetch_pos (match_info, 2, &start_pos, &end_pos); content_length = end_pos - start_pos; g_match_info_free (match_info); g_free (old_content); } *after_end_line = cur_line; *after_end_column = cur_column; finish: if (success) { Token *token = g_slice_new (Token); token->type = instr; token->command = command; token->content = content; token->content_length = content_length; token->line = start_line; token->column = start_column; token->content_column = start_column + content_offset; token->owns_content = TRUE; token->owns_command = TRUE; return token; } else { g_free (command); g_free (content); return NULL; } }