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;
}
Ejemplo n.º 3
0
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;
    }
}
Ejemplo n.º 4
0
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;
    }
}