Ejemplo n.º 1
0
handle_t handle_alloc (void *table)
{
	HandleTable_t	*ht = (HandleTable_t *) table;
	HandleBlock_t	*bp;
	unsigned long	*wp;
	unsigned	h;

	h_printf ("handle_alloc (t): ");
	if (!ht || !ht->free_handles) {
		h_printf ("0\r\n");
		return (0);
	}
	bp = ht->blocks [ht->first_free];
	wp = &bp->bitmap [bp->first_free];
	h = clz (*wp);
	h |= bp->first_free << WORD_SHIFT;
	h |= bp->offset << BLOCK_SHIFT;
	*wp &= ~(1UL << (WORDSIZE - 1UL - h));
	if (--bp->free_bits) {
		while (*wp == 0UL) {
			bp->first_free++;
			wp++;
		}
	}
	else
		while (!ht->blocks [++ht->first_free]->free_bits)
			;
	ht->free_handles--;
	h_printf1 ("%u\r\n", h + 1);
	return (h + 1);
}
Ejemplo n.º 2
0
/**
 *    This is the global IRQ handler on this platform!
 *    It is based on the assembler code found in the Broadcom datasheet.
 *
 **/
void irqHandler() {
    register unsigned long ulMaskedStatus;
    register unsigned long irqNumber;

    ulMaskedStatus = pRegs->IRQBasic;

    /* Bits 7 through 0 in IRQBasic represent interrupts 64-71 */
    if (ulMaskedStatus & 0xFF) {
        irqNumber=64 + 31;
    }

    /* Bit 8 in IRQBasic indicates interrupts in Pending1 (interrupts 31-0) */
    else if(ulMaskedStatus & 0x100) {
        ulMaskedStatus = pRegs->Pending1;
        irqNumber = 0 + 31;
    }

    /* Bit 9 in IRQBasic indicates interrupts in Pending2 (interrupts 63-32) */
    else if(ulMaskedStatus & 0x200) {
        ulMaskedStatus = pRegs->Pending2;
        irqNumber = 32 + 31;
    }

    else {
        // No interrupt avaialbe, so just return.
        return;
    }

    /* Keep only least significant bit, in case multiple interrupts have occured */
    ulMaskedStatus&=-ulMaskedStatus;
    /* Some magic to determine number of interrupt to serve */
    irqNumber=irqNumber-clz(ulMaskedStatus);
    /* Call interrupt handler */
    g_VectorTable[irqNumber].pfnHandler(irqNumber, g_VectorTable[irqNumber].pParam);
}
Ejemplo n.º 3
0
//为除计算之用的减法
void dsub(char a[],char b[])
{
    int i,alen,blen;
    char r,t,jiewei=0;
    char *pb ;
    alen = strlen(a);
    blen = strlen(b);
    pb = (char *)calloc(alen,sizeof(char));
    //使pb与a位数对齐//
    memset(pb,'0',alen);
    t = alen;
    for(i=blen-1;i>=0;i--)
        pb[--t]=b[i];
    
    
    for(i=alen-1;i>=0;i--) //相减运算
    {
        t = a[i]-jiewei;
        if(t<pb[i]) jiewei=1;
        else jiewei = 0;
        r = (t+jiewei*10)-pb[i];
        a[i] = r+'0';
    }
    a[alen]='\0';
    clz(a);
    free(pb);
}
Ejemplo n.º 4
0
C_RESULT uvlc_decode( video_stream_t* const stream, int32_t* run, int32_t* level, int32_t* last)
{
  uint32_t stream_code, stream_length;
  int32_t r = 0, z, sign;

  stream_code = stream_length = 0;

  // Peek 32 bits from stream because we know our datas fit in
  video_peek_data( stream, &stream_code, 32 );


  /// Decode number of zeros
  z = clz(stream_code);

  stream_code  <<= z + 1; // Skip all zeros & 1
  stream_length += z + 1;

  if( z > 1 )
  {
    r = stream_code >> (32 - (z-1));

    stream_code   <<= (z-1);
    stream_length  += (z-1);

    *run = r + (1 << (z-1));
  }
Ejemplo n.º 5
0
Archivo: mpu.c Proyecto: InSoonPark/asf
/*!
 * \brief Converts an input region size expressed in kBytes to the corresponding
 *  eRegionSize type value.
 *
 * \param kBSizeValue: input region size expressed in kBytes
 * \param peRegionSizeValue: output region size in the eRegionSize type
 *
 * \return bool true if the conversion succeeded
 *              false if the conversion failed (the input is not a possible protected region size).
 */
bool mpu_convert_kbsize_to_eregionsize(eRegionSize *peRegionSizeValue, U32 kBSizeValue)
{
  U32 Log2kBSize;
  eRegionSize RegVal;

  // The size must be non-zero.
  if (!kBSizeValue)
    return false;

  // Compute the logarithm to base 2 of the size expressed in kB.
  Log2kBSize = 32 - (clz(kBSizeValue) + 1);

  // The size must be a power of 2.
  if (kBSizeValue != 1 << Log2kBSize)
    return false;

  // MPUARx.SIZE is (the logarithm to base 2 of the size expressed in bytes) - 1.
  RegVal = (eRegionSize)(10 + Log2kBSize - 1);

  // The size must be in the allowed range.
  if (RegVal <= MPU_REGION_SIZE_LOWLIMIT_FORBIDDEN ||
      RegVal >= MPU_REGION_SIZE_HIGHLIMIT_FORBIDDEN)
    return false;

  *peRegionSizeValue = RegVal;
  return true;
}
Ejemplo n.º 6
0
/*
 * Version of ffs that only looks at bits 12..15.
 */
static inline unsigned int irq_ffs(unsigned int pending)
{
#if defined(CONFIG_CPU_MIPS32) || defined(CONFIG_CPU_MIPS64)
	return -clz(pending) + 31 - CAUSEB_IP;
#else
	unsigned int a0 = 7;
	unsigned int t0;

	t0 = pending & 0xf000;
	t0 = t0 < 1;
	t0 = t0 << 2;
	a0 = a0 - t0;
	pending = pending << t0;

	t0 = pending & 0xc000;
	t0 = t0 < 1;
	t0 = t0 << 1;
	a0 = a0 - t0;
	pending = pending << t0;

	t0 = pending & 0x8000;
	t0 = t0 < 1;
	/* t0 = t0 << 2; */
	a0 = a0 - t0;
	/* pending = pending << t0; */

	return a0;
#endif
}
/*!
  \fn       int ifx_rcu_rst(unsigned int reset_domain_id, unsigned int module_id)
  \brief    Trigger reset of one hardware module.

            User uses this function to trigger reset of one hardware module.
            Driver will give notification to all drivers/components registering
            for reset of this hardware module.

  \param    reset_domain_id - unsigned int, hardware module ID
  \param    module_id       - unsigned int, driver/component module ID
  \return   IFX_SUCCESS     Reset successfully.
  \return   IFX_ERROR       Reset fail.
  \ingroup  IFX_RCU_API
 */
int ifx_rcu_rst(unsigned int reset_domain_id, unsigned int module_id)
{
    unsigned long sys_flags;
    unsigned int domain_id_bits;
    int domain_id;
    ifx_rcu_handler_t *p_cur;

    spin_lock_irqsave(&g_rcu_lock, sys_flags);
    //  trigger pre-reset event, each handler must be as fast as possible, because interrupt is disabled
    domain_id_bits = g_rcu_domains[reset_domain_id].affected_domains;
    while ( domain_id_bits != 0 ) {
        domain_id = clz(domain_id_bits);
        domain_id_bits ^= 1 << domain_id;

        for ( p_cur = g_rcu_domains[domain_id].handlers; p_cur != NULL; p_cur = p_cur->next )
            if ( p_cur->module_id != module_id )
                p_cur->fn(domain_id, module_id, 0, p_cur->arg);
    }
    //  issue reset
    ifx_rcu_rst_req_write(g_rcu_domains[reset_domain_id].rst_req_value, g_rcu_domains[reset_domain_id].rst_req_mask);
    if ( g_rcu_domains[reset_domain_id].latch ) {
        udelay(g_rcu_domains[reset_domain_id].udelay);
        ifx_rcu_rst_req_write(~g_rcu_domains[reset_domain_id].rst_req_value, g_rcu_domains[reset_domain_id].rst_req_mask);
    }
    else {
        int max_count = 1000;

        while ( (ifx_rcu_rst_stat_read() & g_rcu_domains[reset_domain_id].rst_stat_mask) && max_count-- );
        if ( max_count < 0 ) {
            err("timeout during reset domain - %s", g_rcu_domain_name[reset_domain_id]);
        }
    }
    //  trigger post-reset event, each handler must be as fast as possible, because interrupt is disabled
    domain_id_bits = g_rcu_domains[reset_domain_id].affected_domains;
    while ( domain_id_bits != 0 ) {
        domain_id = clz(domain_id_bits);
        domain_id_bits ^= 1 << domain_id;

        for ( p_cur = g_rcu_domains[domain_id].handlers; p_cur != NULL; p_cur = p_cur->next )
            if ( p_cur->module_id != module_id )
                p_cur->fn(domain_id, module_id, 1, p_cur->arg);
    }
    spin_unlock_irqrestore(&g_rcu_lock, sys_flags);

    return IFX_SUCCESS;
}
Ejemplo n.º 8
0
__int_handler _get_interrupt_handler(uint32_t int_level)
{
	/* ICR3 is mapped first, ICR0 last.
	Code in exception.S puts int_level in R12 which is used by the compiler
	to pass a single argument to a function. */
	uint32_t int_grp = AVR32_INTC.icr[AVR32_INTC_INT3 - int_level];
	uint32_t int_req = AVR32_INTC.irr[int_grp];

	/* As an interrupt may disappear while it is being fetched by the CPU
	(spurious interrupt caused by a delayed response from an MCU peripheral
	to an interrupt flag clear or interrupt disable instruction), check if 
	there are remaining interrupt lines to process.
	If a spurious interrupt occurs, the status register (SR) contains an
	execution mode and interrupt level masks corresponding to a level 0
	interrupt, whatever the interrupt priority level causing the spurious
	event. This behavior has been chosen because a spurious interrupt has
	not to be a priority one and because it may not cause any trouble to 
	other interrupts.
	However, these spurious interrupts place the hardware in an unstable
	state and could give problems in other/future versions of the CPU, so 
	the software has to be written so that they never occur. The only safe 
	way of achieving this is to always clear or disable peripheral 
	interrupts with the following sequence:
	1: Mask the interrupt in the CPU by setting GM (or IxM) in SR.
	2: Perform the bus access to the peripheral register that clears or
	disables the interrupt.
	3: Wait until the interrupt has actually been cleared or disabled by the
	peripheral. This is usually performed by reading from a register in the
	same peripheral (it DOES NOT have to be the same register that was
	accessed in step 2, but it MUST be in the same peripheral), what takes
	bus system latencies into account, but peripheral internal latencies
	(generally 0 cycle) also have to be considered.
	4: Unmask the interrupt in the CPU by clearing GM (or IxM) in SR.
	Note that steps 1 and 4 are useless inside interrupt handlers as the
	corresponding interrupt level is automatically masked by IxM (unless IxM
	is explicitly cleared by the software).*/

	/* Get the right IRQ handler.

	If several interrupt lines are active in the group, the interrupt line
	with the highest number is selected. This is to be coherent with the
	prioritization of interrupt groups performed by the hardware interrupt
	controller.
	
	If no handler has been registered for the pending interrupt,
	_unhandled_interrupt will be selected thanks to the initialization of
	_int_line_handler_table_x by INTC_init_interrupts.
	
	exception.S will provide the interrupt handler with a clean interrupt 
	stack frame, with nothing more pushed onto the stack. The interrupt 
	handler must manage the `rete' instruction, which can be done using
	pure assembly, inline assembly or the `__attribute__((__interrupt__))' 
	C function attribute.*/
	return (int_req) 
		? _int_handler_table[int_grp]._int_line_handler_table[32 
			- clz(int_req) - 1] 
		: NULL;
}
Ejemplo n.º 9
0
FastDivision<uint64>::FastDivision(uint64 n) {
  // n should be < 2^63.
  if (n == 1) {
    shamt = 0;
    magic_num = 1;
  } else {
    shamt = 127 - clz(n - 1);
    magic_num = div128_64_small((uint128(1) << shamt) + n - 1, n);
  }
  mod = n;
}
Ejemplo n.º 10
0
unsigned int flashc_set_bootloader_protected_size (unsigned int bootprot_size)
{
    flashc_set_gp_fuse_bitfield (AVR32_FLASHC_FGPFRLO_BOOTPROT_OFFSET,
                                 AVR32_FLASHC_FGPFRLO_BOOTPROT_SIZE,
                                 (1 << AVR32_FLASHC_FGPFRLO_BOOTPROT_SIZE) - 1 -
                                 ((bootprot_size) ?
                                  32 - clz ((((min (max (bootprot_size, AVR32_FLASHC_PAGE_SIZE << 1),
                                                    AVR32_FLASHC_PAGE_SIZE <<
                                                    ((1 << AVR32_FLASHC_FGPFRLO_BOOTPROT_SIZE) - 1)) +
                                               AVR32_FLASHC_PAGE_SIZE - 1) / AVR32_FLASHC_PAGE_SIZE) << 1) - 1) - 1 : 0));
    return flashc_get_bootloader_protected_size ();
}
Ejemplo n.º 11
0
FastDivision<uint32>::FastDivision(uint32 n) {
  // n should be < 2^31.
  if (n == 1) {
    shamt = 0;
    magic_num = 1;
  } else {
    shamt = 63 - clz(n - 1);
    // magic_num = ((uint64(1) << (63 - shamt)) + n - 1) / n; // slow
    magic_num = div64_32_small((uint64(1) << shamt) + n - 1, n);
  }
  mod = n;
}
Ejemplo n.º 12
0
sjniFld::sjniFld(JNIEnv *aEnv, /* const char *aClsName, */ jclass ownerCls, const char *name, const char *sig): obj(0), clsName(0), cls(0)
{
	env = aEnv;
	if (sig[0] == 'L')
	{
		clsName = strdup(sig + 1);
		clsName[strlen(clsName)-1] = 0;
		sjniCls clz(env, clsName);
		cls = (jclass) env->NewLocalRef(clz.jcls()); _SJNI_INC_REF_COUNT2(cls);
	}
	// cls = aCls;
	fieldID = env->GetFieldID(ownerCls, name, sig); _SJNI_FNFE_Z(fieldID, name, sig, ownerCls);
}
Ejemplo n.º 13
0
sjniSFld::sjniSFld(JNIEnv *aEnv, /* const char *aClsName, */ jclass aCls, const char *name, const char *sig): clsName(0), cls(0), fieldCls(0) // obj(0)
{
	env = aEnv;
	cls = aCls;
	if (sig[0] == 'L')
	{
		clsName = strdup(sig + 1);
		clsName[strlen(clsName) - 1] = 0;
		// cls = aCls;
		sjniCls clz(env, clsName);
		fieldCls = (jclass) env->NewLocalRef(clz.jcls()); _SJNI_INC_REF_COUNT2(fieldCls);
	}
	cls = (jclass) env->NewLocalRef(aCls); _SJNI_INC_REF_COUNT2(cls);
	fieldID = env->GetStaticFieldID(cls, name, sig); _SJNI_FNFE_Z(fieldID, name, sig, cls);
}
Ejemplo n.º 14
0
/**
 *	This is the global IRQ handler on this platform!
 *	It is based on the assembler code found in the Broadcom datasheet.
 *
 **/
void vApplicationIRQHandler() {
    register uint32_t ulMaskedStatus;
    register uint32_t irqNumber;
    register uint32_t tmp;

    ulMaskedStatus = RPI_IRQ->BASIC_PENDING;
    tmp = ulMaskedStatus & 0x00000300;	// Check if anything pending in pr1/pr2.

    if (ulMaskedStatus & ~0xFFFFF300) {	// Note how we mask out the GPU interrupt Aliases.
        irqNumber = 64 + 31;	// Shifting the basic ARM IRQs to be IRQ# 64 +
        goto emit_interrupt;
    }

    if (tmp & 0x100) {
        ulMaskedStatus = RPI_IRQ->PENDING_1;
        irqNumber = 0 + 31;
        // Clear the interrupts also available in basic IRQ pending reg.
        //ulMaskedStatus &= ~((1 << 7) | (1 << 9) | (1 << 10) | (1 << 18) | (1 << 19));
        if (ulMaskedStatus) {
            goto emit_interrupt;
        }
    }

    if (tmp & 0x200) {
        ulMaskedStatus = RPI_IRQ->PENDING_2;
        irqNumber = 32 + 31;
        // Don't clear the interrupts in the basic pending, simply allow them to processed here!
        if (ulMaskedStatus) {
            goto emit_interrupt;
        }
    }

    //return;

    emit_interrupt:

    tmp = ulMaskedStatus - 1;
    ulMaskedStatus = ulMaskedStatus ^ tmp;

    uint32_t lz = clz(ulMaskedStatus);
    irqNumber = irqNumber - lz;

    if (g_rpi_irq_table[irqNumber].pHandler) {
        g_rpi_irq_table[irqNumber].pHandler(irqNumber, g_rpi_irq_table[irqNumber].pParam);
    }
}
Ejemplo n.º 15
0
Ipp32u
aac_huff_decode_sf(Ipp8u** pp_bs, Ipp32s* p_offset)
{
  Ipp32u data;
  Ipp32s index;
  Ipp32s shift;

  data = 0;

  data  += (pp_bs[0])[0];
  data <<= 8;

  data  += (pp_bs[0])[1];
  data <<= 8;

  data  += (pp_bs[0])[2];
  data <<= 8;

  data  += (pp_bs[0])[3];

  data <<= p_offset[0];

  if (!(data & 0x80000000))
  {
    p_offset[0] ++;
    pp_bs[0] += (p_offset[0] / 8);
    p_offset[0] %= 8;
    return 60;
  }

  index = clz(~data);
  data <<= index;
  shift = sf_table[index] & 0xFF;
  index = sf_table[index] >> 8;

  data >>= shift;
  data = sf_table[index+data];
  shift = data & 0xFF;
  data >>= 8;
  p_offset[0] += shift;
  pp_bs[0] += (p_offset[0] / 8);
  p_offset[0] %= 8;
  return data;
}
Ejemplo n.º 16
0
size_t lcs(const kmer_t & a, const kmer_t & b, size_t k) {
    static const size_t num_blocks = bitwidth<kmer_t>::width/BLOCK_WIDTH;
    //kmer_t x = a ^ b; // Do this in the loop below instead to potentially save some cycles
    uint64_t * p = (uint64_t*)&a;
    uint64_t * q = (uint64_t*)&b;
    size_t total = 0;
    // This should unroll. for 128 bits its only 2 iters
    for (size_t i = 0; i < num_blocks; i++) {
        if (p[i] == q[i]) {
            total += BLOCK_WIDTH;
            continue;
        }
        else {
            // COUNT *LEADING* ZEROS - we store kmers backwards
            total += clz(p[i] ^ q[i]);
            break;
        }
    }
    total /= NT_WIDTH;
    return std::min(total, k);
}
static inline int print_reset_domain(char *buf, int i)
{
    int len = 0;
    unsigned int domain_id_bits;
    int domain_id;
    int flag;

    len += sprintf(buf + len,       "Reset Domain - %s\n", g_rcu_domain_name[i]);
    flag = 0;
    domain_id_bits = g_rcu_domains[i].affected_domains & ~(1 << i);
    while ( domain_id_bits != 0 ) {
        domain_id = clz(domain_id_bits);
        domain_id_bits ^= 1 << domain_id;

        if ( !flag ) {
            len += sprintf(buf + len, "  affected domains: %s", g_rcu_domain_name[domain_id]);
            flag++;
        }
        else
            len += sprintf(buf + len, ", %s", g_rcu_domain_name[domain_id]);

        if ( domain_id_bits == 0 )
            len += sprintf(buf + len, "\n");
    }
    len += sprintf(buf + len,       "  rst_req_value - %#08x, rst_req_mask - %#08x, rst_stat_mask - %#08x\n", g_rcu_domains[i].rst_req_value, g_rcu_domains[i].rst_req_mask, g_rcu_domains[i].rst_stat_mask);
    if ( g_rcu_domains[i].latch )
        len += sprintf(buf + len,   "  latch mode, udelay - %d\n", g_rcu_domains[i].udelay);
    else
        len += sprintf(buf + len,   "  pulse mode\n");
    if ( g_rcu_domains[i].handlers )
        len += sprintf(buf + len,   "  handlers:\n");
    else
        len += sprintf(buf + len,   "  handlers: NULL\n");

    return len;
}
Ejemplo n.º 18
0
/* ! \brief Gets the interrupt handler of the current event at the \a int_level interrupt priority level (called from exception.S). \param int_level
   Interrupt priority level to handle. \return Interrupt handler to execute. \note Taken and adapted from Newlib. */
__int_handler _get_interrupt_handler (unsigned int int_level)
{
    // ICR3 is mapped first, ICR0 last.
    // Code in exception.S puts int_level in R12 which is used by AVR32-GCC to
    // pass a single argument to a function.
    unsigned int int_grp = AVR32_INTC.icr[AVR32_INTC_INT3 - int_level];
    unsigned int int_req = AVR32_INTC.irr[int_grp];
#ifdef TIME_MEASURING_ENABLE
    unsigned int n;
#endif
    // As an interrupt may disappear while it is being fetched by the CPU
    // (spurious interrupt caused by a delayed response from an MCU peripheral to
    // an interrupt flag clear or interrupt disable instruction), check if there
    // are remaining interrupt lines to process.
    // If a spurious interrupt occurs, the status register (SR) contains an
    // execution mode and interrupt level masks corresponding to a level 0
    // interrupt, whatever the interrupt priority level causing the spurious
    // event. This behavior has been chosen because a spurious interrupt has not
    // to be a priority one and because it may not cause any trouble to other
    // interrupts.
    // However, these spurious interrupts place the hardware in an unstable state
    // and could give problems in other/future versions of the CPU, so the
    // software has to be written so that they never occur. The only safe way of
    // achieving this is to always clear or disable peripheral interrupts with the
    // following sequence:
    // 1: Mask the interrupt in the CPU by setting GM (or IxM) in SR.
    // 2: Perform the bus access to the peripheral register that clears or
    // disables the interrupt.
    // 3: Wait until the interrupt has actually been cleared or disabled by the
    // peripheral. This is usually performed by reading from a register in the
    // same peripheral (it DOES NOT have to be the same register that was
    // accessed in step 2, but it MUST be in the same peripheral), what takes
    // bus system latencies into account, but peripheral internal latencies
    // (generally 0 cycle) also have to be considered.
    // 4: Unmask the interrupt in the CPU by clearing GM (or IxM) in SR.
    // Note that steps 1 and 4 are useless inside interrupt handlers as the
    // corresponding interrupt level is automatically masked by IxM (unless IxM is
    // explicitly cleared by the software).
    //
    // Get the right IRQ handler.
    //
    // If several interrupt lines are active in the group, the interrupt line with
    // the highest number is selected. This is to be coherent with the
    // prioritization of interrupt groups performed by the hardware interrupt
    // controller.
    //
    // If no handler has been registered for the pending interrupt,
    // _unhandled_interrupt will be selected thanks to the initialization of
    // _int_line_handler_table_x by INTC_init_interrupts.
    //
    // exception.S will provide the interrupt handler with a clean interrupt stack
    // frame, with nothing more pushed onto the stack. The interrupt handler must
    // manage the `rete' instruction, what can be done thanks to pure assembly,
    // inline assembly or the `__attribute__((__interrupt__))' C function
    // attribute.

#ifdef TIME_MEASURING_ENABLE

    n = TIME_MEASURING_INT_IntTableOffset[int_grp] + (32 - clz (int_req) - 1);

    if (0 != int_req)
    {
        if (TIME_MEASURING_INT_MAX_ENTRYS > n)
        {
            TIME_MEASURING_INT_IntCount[n]++;
        }
        else
        {
            TIME_MEASURING_INT_IntCount[TIME_MEASURING_INT_UNKONWN]++;
        }
    }
    else
    {
        TIME_MEASURING_INT_IntCount[TIME_MEASURING_INT_UNKONWN]++;
    }
#endif

    return (int_req) ? _int_handler_table[int_grp]._int_line_handler_table[32 - clz (int_req) - 1] : NULL;
}
Ejemplo n.º 19
0
void uvlc_encode( video_stream_t* const stream, int32_t level, int32_t run, int32_t not_last )
{
  int32_t sign, length, data, value_code, value_length;

  /// Encode number of zeros
  data = run;

  length      = 0;
  value_code  = 1;

  if( data > 0 )
  {
    length = 32 - clz(data);      // compute number of bits used in run ( = length of run )
    data  -= 1 << ( length - 1 ); // compute value of run
  }

  value_length  = length + 1;

  length -= 1;
  if( length > 0 )
  {
    PACK_BITS( value_code, value_length, data, length );
  }

  /// Encode level
  data = level;

  // sign handling
  sign = 0;
  if( data < 0 )
  {
    data = -data;
    sign = 1;
  }

  // TODO Check saturation & if level == -128
  length = 32 - clz(data);  // number of bits used in level ( = length of level )
  if( length > 1 )
  {
    data   -= 1 << (length - 1);
    length += 1;
  }

  PACK_BITS( value_code, value_length, 1, length );

  VP_OS_ASSERT( length != 2 );

  length -= 2;
  if(length > 0)
  {
    PACK_BITS( value_code, value_length, data, length );
  }

  PACK_BITS( value_code, value_length, sign, 1 );

  /// Encode last
  // add sequence for end of block if required
  if( not_last == 0 )
  {
    PACK_BITS( value_code, value_length, 0x5, 3 );
  }

  /// Write output
  video_write_data( stream, value_code, value_length );
}
Ejemplo n.º 20
0
/**
 * Centralized Interrupt dispatcher routine. This routine dispatches interrupts
 * to the user ISR. The priority is according to the blackfin SIC.
 * The first level of priority is handled in the hardware at the core event
 * controller. The second level of interrupt is handled according to the line
 * number that goes in to the SIC.
 * * SIC_0 has higher priority than SIC 1.
 * * Inside the SIC the priority is assigned according to the line number.
 *   Lower the line number higher the priority.
 *
 *   In order to change the interrupt priority we may
 *   1. change the SIC IAR registers or
 *   2. Assign priority and extract it inside this function and call the ISR
 *   according tot the priority.
 *
 * @param vector IVG number.
 * @return
 */
static rtems_isr interruptHandler(rtems_vector_number vector) {
  uint32_t mask = 0;
  int id = 0;
  /**
   * Enable for debugging
   *
   * static volatile uint32_t spurious_sic0    = 0;
   * static volatile uint32_t spurious_source  = 0;
   * static volatile uint32_t spurious_sic1    = 0;
   */

  /**
   * Extract the vector number relative to the SIC start line
   */
  vector -= CEC_INTERRUPT_BASE_VECTOR;

  /**
   * Check for bounds
   */
  if (vector >= 0 && vector < CEC_INTERRUPT_COUNT) {

    /**
     * Extract information and execute ISR from SIC 0
     */
    mask = *(uint32_t volatile *) SIC_ISR &
        *(uint32_t volatile *) SIC_IMASK & vectors[vector].mask0;
    id      = clz(mask);
    if ( SIC_ISR0_MAX > id ) {
      /** Parameter check */
      if( NULL != ivt[id].pFunc) {
        /** Call the relevant function with argument */
        ivt[id].pFunc( ivt[id].pArg );
      } else {
        /**
         * spurious interrupt we should not be getting this
         * spurious_sic0++;
         * spurious_source = id;
         */
      }
    } else {
      /**
       * we look at SIC 1
       */
    }


    /**
     * Extract information and execute ISR from SIC 1
     */
    mask    = *(uint32_t volatile *) (SIC_ISR + SIC_ISR_PITCH) &
        *(uint32_t volatile *) (SIC_IMASK + SIC_IMASK_PITCH) &
        vectors[vector].mask1;
    id      = clz(mask)+SIC_ISR0_MAX;
    if ( IRQ_MAX > id ) {
      /** Parameter Check */
      if( NULL != ivt[id].pFunc ) {
        /** Call the relevant function with argument */
        ivt[id].pFunc( ivt[id].pArg );
      } else {
        /**
         * spurious interrupt we should not be getting this
         *
         * spurious_sic1++;
         * spurious_source = id;
         */
      }
    } else {
      /**
       * we continue
       */
    }

  }
}
static inline int filterShiftU8bit(uint32_t posGain){
    return 31-clz(posGain);
}
Ejemplo n.º 22
0
void Rasterizer::subdivideTile( 
	int acceptCornerValue1, 
	int acceptCornerValue2, 
	int acceptCornerValue3,
	int rejectCornerValue1, 
	int rejectCornerValue2,
	int rejectCornerValue3,
	vec16<int> acceptStep1, 
	vec16<int> acceptStep2, 
	vec16<int> acceptStep3, 
	vec16<int> rejectStep1, 
	vec16<int> rejectStep2, 
	vec16<int> rejectStep3, 
	int tileSize,
	int left,
	int top)
{
	vec16<int> acceptEdgeValue1;
	vec16<int> acceptEdgeValue2;
	vec16<int> acceptEdgeValue3;
	vec16<int> rejectEdgeValue1;
	vec16<int> rejectEdgeValue2;
	vec16<int> rejectEdgeValue3;
	int trivialAcceptMask;
	int trivialRejectMask;
	int recurseMask;
	int index;
	int x, y;
	
#if 0
	printf("subdivideTile(%08x, %08x, %08x, %08x, %08x, %08x,\n",
		acceptCornerValue1, 
		acceptCornerValue2, 
		acceptCornerValue3,
		rejectCornerValue1, 
		rejectCornerValue2,
		rejectCornerValue3);
	acceptStep1.print(); printf("\n"); 
	acceptStep2.print(); printf("\n");
	acceptStep3.print(); printf("\n");
	rejectStep1.print(); printf("\n");
	rejectStep2.print(); printf("\n");
	rejectStep3.print(); printf("\n");
#endif

	// Compute accept masks
	acceptEdgeValue1 = acceptStep1 + acceptCornerValue1;
	trivialAcceptMask = acceptEdgeValue1 <= 0;
	acceptEdgeValue2 = acceptStep2 + acceptCornerValue2;
	trivialAcceptMask &= acceptEdgeValue2 <= 0;
	acceptEdgeValue3 = acceptStep3 + acceptCornerValue3;
	trivialAcceptMask &= acceptEdgeValue3 <= 0;

	if (tileSize == 4)
	{
		// End recursion
		fShaderState->fillMasked(left, top, trivialAcceptMask);
		return;
	}

	// Reduce tile size for sub blocks
	tileSize = tileSize / 4;

	// Process all trivially accepted blocks
	if (trivialAcceptMask != 0)
	{
		int index;
		int currentMask = trivialAcceptMask;
	
		while ((index = clz(currentMask)) >= 0)
		{			
			currentMask &= ~(1 << index);
			int blockLeft = left + tileSize * ((15 - index) & 3);
			int blockTop = top + tileSize * ((15 - index) >> 2);
			for (int y = 0; y < tileSize; y += 4)
			{
				for (int x = 0; x < tileSize; x += 4)
					fShaderState->fillMasked(blockLeft + x, blockTop + y, 0xffff);
			}
		}
	}
Ejemplo n.º 23
0
static void handle_iep_interrupt(void)
{
	uint16_t intrs = read_otg_daint() & 0xffff;
	uint32_t ep_intr, txstatus, short_data;
	unsigned ep, xfersize, dwords, xfered;

	while (intrs) {
		ep = 31 - clz(intrs);
		ep_intr = read_diep_int(ep);
		intrs &= ~(1 << ep);

		if (!(ep_intr & DEP_TXFIFO_EMPTY))
			continue;

		if (!(read_diep_empmsk() & (1 << ep)))
			continue;

		xfered = 0;

		while (in_data.size) {
			xfersize = min_t(unsigned, in_data.size, dwc2_max_packet_size(ep));
			dwords = DIV_ROUND_UP(xfersize, 4);
			txstatus = read_dtxfsts(ep);

			if (txstatus < dwords)
				break;

			while (xfersize >= 4) {
				volatile uint32_t *ptr = (uint32_t *)in_data.data;
				uint32_t val = *ptr;

				debug(">> 0x");
				debug_hex(val, 8);
				debug("\n");
				write_ep_fifo(ep, val);

				in_data.data += 4;
				in_data.size -= 4;
				xfered += 4;
				xfersize -= 4;
			}

			if (!xfersize)
				break;

			short_data = 0;
			while (xfersize > 0) {
				volatile uint8_t *ptr = (uint8_t *)in_data.data;

				short_data <<= 8;
				short_data |= *ptr;

				in_data.data++;
				in_data.size--;
				xfered++;
				xfersize--;
			}

			debug(">> 0x");
			debug_hex(short_data, (xfered % 4) * 2);
			debug("\n");
			write_ep_fifo(ep, short_data);
		}

		set_diep_int(ep, DEP_TXFIFO_EMPTY);

		if (xfered) {
			while (!(read_diep_int(ep) & DEP_XFER_COMP));
			set_diep_int(ep, DEP_XFER_COMP);
			clear_diep_empmsk(1 << ep);
			set_doep_ctl(ep, DEP_ENA_BIT | DEP_CLEAR_NAK);
			if (ep_intr & DEP_NAK_INT)
				set_diep_int(ep, DEP_NAK_INT);
		}
	}
}
Ejemplo n.º 24
0
Archivo: pwm_dac.c Proyecto: avrxml/asf
/*! \brief Returns the logarithm to base 2 of the aligned byte size required to
 *         store the \a bit_size bit size saturated to the range [|8, 32|].
 */
static __inline__ size_t pwm_dac_get_log2_aligned_byte_size(size_t bit_size)
{
  return 32 - clz((min(max(bit_size, 8), 32) << 1) - 1) - 1 - 3;
}
Ejemplo n.º 25
0
void mfcc_calc( Mfcc *pMfcc, AUD_Int32s *Xabs, AUD_Int32s *mfcc )
{
	AUD_Int32s lz, minLz;
	AUD_Int32s i, j, k;

	/* find the number of leading zeros in the largest number */
	minLz = 32;
	for ( k = 0; k < pMfcc->fftLen; k++ )
	{
		lz = clz( Xabs[k] );
		if ( lz < minLz )
		{
			minLz = lz;
		}
	}
	/* scale down the to have at least 15 leading zeros to prevent saturation in next step */
	if ( minLz < 15 )
	{
		for ( k = 0; k < pMfcc->fftLen; k++ )
		{
			Xabs[k] = Xabs[k] >> (15 - minLz);
		}
	}

	/* filter bank calculation */
	melfb_calc( pMfcc->pFb, Xabs, pMfcc->fbBuffer );

	if ( pMfcc->compressType == AUD_AMPCOMPRESS_LOG )
	{
		for ( k = 0; k < pMfcc->fbLen; k++ )
		{
			/* make sure we have no zeros in the ln() calulation */
			if ( pMfcc->fbBuffer[k] <= 0 )
			{
				pMfcc->fbBuffer[k] = 1;
			}

			pMfcc->fbBuffer[k] = fp_ln( pMfcc->fbBuffer[k] );
		}
	}
	else if ( pMfcc->compressType == AUD_AMPCOMPRESS_ROOT )
	{
		for ( k = 0; k < pMfcc->fbLen; k++ )
		{
			// in noisy environment, a bigger root lead to better feature discriminative capability
			// refer to "Improving the noise-robustness of mel-frequency cepstral coefficients for speech recognition"
			if ( pMfcc->fbBuffer[k] <= 0 )
			{
				pMfcc->fbBuffer[k] = 0;
			}
			else
			{
				pMfcc->fbBuffer[k] = (AUD_Int32s)round( pow( pMfcc->fbBuffer[k] / 65536.0, 0.14 ) * 65536.0 );
			}
		}
	}
	else
	{
		AUD_ASSERT( 0 );
	}

	/* DCT calculation */
	dct_calc( pMfcc->pDct, pMfcc->fbBuffer, mfcc );

	/* buffering */
	for ( i = RAW_BUFLEN - 1; i >= 1; i-- )
	{
		for ( j = 0; j < pMfcc->mfccLen; j++ )
		{
			pMfcc->pState[i][j] = pMfcc->pState[i - 1][j];
		}
	}
	for ( j = 0; j < pMfcc->mfccLen; j++ )
	{
		pMfcc->pState[0][j] = mfcc[j];
	}

	return;
}
Ejemplo n.º 26
0
status_t TextureManager::loadTexture(Texture* texture,
        const Region& dirty, const GGLSurface& t)
{
    if (texture->name == -1UL) {
        status_t err = initTexture(texture);
        LOGE_IF(err, "loadTexture failed in initTexture (%s)", strerror(err));
        return err;
    }

    if (texture->target != Texture::TEXTURE_2D)
        return INVALID_OPERATION;

    glBindTexture(GL_TEXTURE_2D, texture->name);

    /*
     * In OpenGL ES we can't specify a stride with glTexImage2D (however,
     * GL_UNPACK_ALIGNMENT is a limited form of stride).
     * So if the stride here isn't representable with GL_UNPACK_ALIGNMENT, we
     * need to do something reasonable (here creating a bigger texture).
     *
     * extra pixels = (((stride - width) * pixelsize) / GL_UNPACK_ALIGNMENT);
     *
     * This situation doesn't happen often, but some h/w have a limitation
     * for their framebuffer (eg: must be multiple of 8 pixels), and
     * we need to take that into account when using these buffers as
     * textures.
     *
     * This should never be a problem with POT textures
     */

    int unpack = __builtin_ctz(t.stride * bytesPerPixel(t.format));
    unpack = 1 << ((unpack > 3) ? 3 : unpack);
    glPixelStorei(GL_UNPACK_ALIGNMENT, unpack);

    /*
     * round to POT if needed
     */
    if (!mGLExtensions.haveNpot()) {
        texture->NPOTAdjust = true;
    }

    if (texture->NPOTAdjust) {
        // find the smallest power-of-two that will accommodate our surface
        texture->potWidth  = 1 << (31 - clz(t.width));
        texture->potHeight = 1 << (31 - clz(t.height));
        if (texture->potWidth  < t.width)  texture->potWidth  <<= 1;
        if (texture->potHeight < t.height) texture->potHeight <<= 1;
        texture->wScale = float(t.width)  / texture->potWidth;
        texture->hScale = float(t.height) / texture->potHeight;
    } else {
        texture->potWidth  = t.width;
        texture->potHeight = t.height;
    }

    Rect bounds(dirty.bounds());
    GLvoid* data = 0;
    if (texture->width != t.width || texture->height != t.height) {
        texture->width  = t.width;
        texture->height = t.height;

        // texture size changed, we need to create a new one
        bounds.set(Rect(t.width, t.height));
        if (t.width  == texture->potWidth &&
            t.height == texture->potHeight) {
            // we can do it one pass
            data = t.data;
        }

        if (t.format == HAL_PIXEL_FORMAT_RGB_565) {
            glTexImage2D(GL_TEXTURE_2D, 0,
                    GL_RGB, texture->potWidth, texture->potHeight, 0,
                    GL_RGB, GL_UNSIGNED_SHORT_5_6_5, data);
        } else if (t.format == HAL_PIXEL_FORMAT_RGBA_4444) {
            glTexImage2D(GL_TEXTURE_2D, 0,
                    GL_RGBA, texture->potWidth, texture->potHeight, 0,
                    GL_RGBA, GL_UNSIGNED_SHORT_4_4_4_4, data);
        } else if (t.format == HAL_PIXEL_FORMAT_RGBA_8888 ||
                   t.format == HAL_PIXEL_FORMAT_RGBX_8888) {
            glTexImage2D(GL_TEXTURE_2D, 0,
                    GL_RGBA, texture->potWidth, texture->potHeight, 0,
                    GL_RGBA, GL_UNSIGNED_BYTE, data);
        } else if (isSupportedYuvFormat(t.format)) {
            // just show the Y plane of YUV buffers
            glTexImage2D(GL_TEXTURE_2D, 0,
                    GL_LUMINANCE, texture->potWidth, texture->potHeight, 0,
                    GL_LUMINANCE, GL_UNSIGNED_BYTE, data);
        } else {
            // oops, we don't handle this format!
            LOGE("texture=%d, using format %d, which is not "
                 "supported by the GL", texture->name, t.format);
        }
    }
    if (!data) {
        if (t.format == HAL_PIXEL_FORMAT_RGB_565) {
            glTexSubImage2D(GL_TEXTURE_2D, 0,
                    0, bounds.top, t.width, bounds.height(),
                    GL_RGB, GL_UNSIGNED_SHORT_5_6_5,
                    t.data + bounds.top*t.stride*2);
        } else if (t.format == HAL_PIXEL_FORMAT_RGBA_4444) {
            glTexSubImage2D(GL_TEXTURE_2D, 0,
                    0, bounds.top, t.width, bounds.height(),
                    GL_RGBA, GL_UNSIGNED_SHORT_4_4_4_4,
                    t.data + bounds.top*t.stride*2);
        } else if (t.format == HAL_PIXEL_FORMAT_RGBA_8888 ||
                   t.format == HAL_PIXEL_FORMAT_RGBX_8888) {
            glTexSubImage2D(GL_TEXTURE_2D, 0,
                    0, bounds.top, t.width, bounds.height(),
                    GL_RGBA, GL_UNSIGNED_BYTE,
                    t.data + bounds.top*t.stride*4);
        } else if (isSupportedYuvFormat(t.format)) {
            // just show the Y plane of YUV buffers
            glTexSubImage2D(GL_TEXTURE_2D, 0,
                    0, bounds.top, t.width, bounds.height(),
                    GL_LUMINANCE, GL_UNSIGNED_BYTE,
                    t.data + bounds.top*t.stride);
        }
    }
    return NO_ERROR;
}
Ejemplo n.º 27
0
/*
 * Formats data LV for a use as a VDO pool LV.
 *
 * Calls tool 'vdoformat' on the already active volume.
 */
static int _format_vdo_pool_data_lv(struct logical_volume *data_lv,
				    const struct dm_vdo_target_params *vtp,
				    uint64_t *logical_size)
{
	char *dpath;
	const struct dm_config_node *cn;
	const struct dm_config_value *cv;
	struct pipe_data pdata;
	FILE *f;
	uint64_t lb;
	unsigned slabbits;
	int args = 1;
	char buf_args[5][128];
	char buf[256]; /* buffer for short disk header (64B) */
	const char *argv[19] = { /* Max supported args */
		find_config_tree_str_allow_empty(data_lv->vg->cmd, global_vdo_format_executable_CFG, NULL)
	};

	if (!(dpath = lv_path_dup(data_lv->vg->cmd->mem, data_lv))) {
		log_error("Failed to build device path for VDO formating of data volume %s.",
			  display_lvname(data_lv));
		return 0;
	}

	if (*logical_size) {
		if (dm_snprintf(buf_args[args], sizeof(buf_args[0]), "--logical-size=" FMTu64 "K",
			       (*logical_size / 2)) < 0)
			return_0;

		argv[args] = buf_args[args];
		args++;
	}

	slabbits = 31 - clz(vtp->slab_size_mb / DM_VDO_BLOCK_SIZE * 512);
	log_debug("Slab size %s converted to %u bits.",
		  display_size(data_lv->vg->cmd, vtp->slab_size_mb * UINT64_C(2 * 1024)), slabbits);
	if (dm_snprintf(buf_args[args], sizeof(buf_args[0]), "--slab-bits=%u", slabbits) < 0)
		return_0;

	argv[args] = buf_args[args];
	args++;

	if (vtp->check_point_frequency) {
		if (dm_snprintf(buf_args[args], sizeof(buf_args[0]), "--uds-checkpoint-frequency=%u",
				vtp->check_point_frequency) < 0)
			return_0;
		argv[args] = buf_args[args];
		args++;
	}

	/* Convert size to GiB units or one of these strings: 0.25, 0.50, 0.75 */
	if (vtp->index_memory_size_mb >= 1024) {
		if (dm_snprintf(buf_args[args], sizeof(buf_args[0]), "--uds-memory-size=%u",
				vtp->index_memory_size_mb / 1024) < 0)
			return_0;
	} else if (dm_snprintf(buf_args[args], sizeof(buf_args[0]), "--uds-memory-size=0.%u",
			       (vtp->index_memory_size_mb < 512) ? 25 :
			       (vtp->index_memory_size_mb < 768) ? 50 : 75) < 0)
		   return_0;

	argv[args] = buf_args[args];
	args++;

	if (vtp->use_sparse_index)  {
		if (dm_snprintf(buf_args[args], sizeof(buf_args[0]), "--uds-sparse") < 0)
			return_0;

		argv[args] = buf_args[args];
		args++;
	}

	/* Any other user opts add here */
	if (!(cn = find_config_tree_array(data_lv->vg->cmd, global_vdo_format_options_CFG, NULL))) {
		log_error(INTERNAL_ERROR "Unable to find configuration for vdoformat command options.");
		return 0;
	}

	for (cv = cn->v; cv && args < 16; cv = cv->next) {
		if (cv->type != DM_CFG_STRING) {
			log_error("Invalid string in config file: "
				  "global/vdoformat_options.");
			return 0;
		}
		if (cv->v.str[0])
			argv[++args] = cv->v.str;
	}

	/* Only unused VDO data LV could be activated and wiped */
	if (!dm_list_empty(&data_lv->segs_using_this_lv)) {
		log_error(INTERNAL_ERROR "Failed to wipe logical VDO data for volume %s.",
			  display_lvname(data_lv));
		return 0;
	}

	argv[args] = dpath;

	if (!(f = pipe_open(data_lv->vg->cmd, argv, 0, &pdata))) {
		log_error("WARNING: Cannot read output from %s.", argv[0]);
		return 0;
	}

	if (!*logical_size)
		while (fgets(buf, sizeof(buf), f)) {
			/* TODO: Watch out for locales */
			if (sscanf(buf, "Logical blocks defaulted to " FMTu64 " blocks", &lb) == 1) {
				*logical_size = lb * DM_VDO_BLOCK_SIZE;
				log_verbose("Available VDO logical blocks " FMTu64 " (%s).",
					    lb, display_size(data_lv->vg->cmd, *logical_size));
				break;
			} else
				log_warn("WARNING: Cannot parse output '%s' from %s.", buf, argv[0]);
		}

	if (!pipe_close(&pdata)) {
		log_error("Command %s failed.", argv[0]);
		return 0;
	}

	return 1;
}
Ejemplo n.º 28
0
//除法计算
void divid(const char a[],const char b[],char result[])
{
    bool isNegative = false;
    char *op1,*pa,*pb,*pr;
    int up,alen,blen,adotp,bdotp,i,k,dotp,t,t1,j,quo_size;
    /////////////判定符号///////////////
    //如果为异号
    if((a[0] == '-'||b[0] == '-')&&a[0] != b[0])
        result[0] = '-',isNegative = true;
    
    //去除负号
    if(a[0] == '-')a++;
    if(b[0] == '-')b++;
    ///////////////////////////////////
    
    alen = strlen(a)-1; //减去一位小数点
    blen = strlen(b)-1;
    
    ///////获取被除数小数点移位后的位置//////////
    adotp = strchr(a,'.')-a;
    bdotp = strchr(b,'.')-b;
    
    //计算商小数点位置
    dotp = adotp+blen-bdotp;
    if(isNegative)dotp++;
    
    //////////准备数据/////////////
    op1 = (char *)calloc(alen+blen+1,sizeof(char));
    pa = (char *)calloc(alen+blen+1,sizeof(char));
    pb = (char *)calloc(blen+1,sizeof(char));
    pr = (char *)calloc(alen+blen+1,sizeof(char));
    
    for(i = 0,t=0; i<=alen; i++)
    {
        if(a[i]!='.')
            pa[t++] = a[i];
    }
    for(;t<dotp-1;t++)
    {
        pa[t] = '0';
    }
    for(;t<blen;t++)
    {
        pa[t] = '0';
    }
    
    pa[t] = '\0';
    for(i = 0,t=0; i<=blen; i++)
    {
        if(b[i]!='.')
            pb[t++] = b[i];
    }
    pb[t] = '\0';
    clz(pa);
    clz(pb);
    ////////取得被除数的高位数op1,且op1大于被除数b//////////
    strncpy(op1,pa,strlen(pb));
    if(strcmp(op1,pb)<0)
    {
        strncpy(op1,pa,strlen(pb)+1);
    }
    
    /////计算//////
    j = k = strlen(op1);
    t1=0;
    quo_size = strlen(pa)+1-k; //获取商的长度
    
    while(t1<quo_size)
    {
        up = 0;
        t = cmp(op1,pb);
        while(t>=0)
        {
            dsub(op1,pb);
            t = cmp(op1,pb);
            up++;
        }
        pr[t1++] = up+'0';
        op1[strlen(op1)]=pa[j++];
        clz(op1);
    }
    quo_size+=50;//加50精度
    while(t1<quo_size&&(cmp(op1,(char *)"0")>0))
    {
        up = 0;
        op1[strlen(op1)]='0';
        t = cmp(op1,pb);
        while(t>=0)
        {
            dsub(op1,pb);
            t = cmp(op1,pb);
            up++;
        }
        pr[t1++] = up+'0';                    
    }
    //////////////////////////////
    
    if(isNegative)t=1;
    else t=0;
    for(i=0;i<=t1;i++)//复制结果并给商加上小数点
    {
        if(t==dotp) result[t++] = '.';
        result[t++]=pr[i];
    }   
    
    
    clz(result);
    clDot(result);
    free(op1);
    free(pa);
    free(pb);
}
void LayerBlur::onDraw(const Region& clip) const
{
    const DisplayHardware& hw(graphicPlane(0).displayHardware());
    const uint32_t fbHeight = hw.getHeight();
    int x = mTransformedBounds.left;
    int y = mTransformedBounds.top;
    int w = mTransformedBounds.width();
    int h = mTransformedBounds.height();
    GLint X = x;
    GLint Y = fbHeight - (y + h);
    if (X < 0) {
        w += X;
        X = 0;
    }
    if (Y < 0) {
        h += Y;
        Y = 0;
    }
    if (w<0 || h<0) {
        // we're outside of the framebuffer
        return;
    }

    if (mTextureName == -1U) {
        // create the texture name the first time
        // can't do that in the ctor, because it runs in another thread.
        glGenTextures(1, &mTextureName);
        glGetIntegerv(GL_IMPLEMENTATION_COLOR_READ_FORMAT_OES, &mReadFormat);
        glGetIntegerv(GL_IMPLEMENTATION_COLOR_READ_TYPE_OES, &mReadType);
        if (mReadFormat != GL_RGB || mReadType != GL_UNSIGNED_SHORT_5_6_5) {
            mReadFormat = GL_RGBA;
            mReadType = GL_UNSIGNED_BYTE;
            mBlurFormat = GGL_PIXEL_FORMAT_RGBX_8888;
        }
    }

    Region::const_iterator it = clip.begin();
    Region::const_iterator const end = clip.end();
    if (it != end) {
#if defined(GL_OES_EGL_image_external)
        if (GLExtensions::getInstance().haveTextureExternal()) {
            glDisable(GL_TEXTURE_EXTERNAL_OES);
        }
#endif
        glEnable(GL_TEXTURE_2D);
        glBindTexture(GL_TEXTURE_2D, mTextureName);

        if (mRefreshCache) {
            mRefreshCache = false;
            mAutoRefreshPending = false;

            int32_t pixelSize = 4;
            int32_t s = w;
            if (mReadType == GL_UNSIGNED_SHORT_5_6_5) {
                // allocate enough memory for 4-bytes (2 pixels) aligned data
                s = (w + 1) & ~1;
                pixelSize = 2;
            }

            uint16_t* const pixels = (uint16_t*)malloc(s*h*pixelSize);

            // This reads the frame-buffer, so a h/w GL would have to
            // finish() its rendering first. we don't want to do that
            // too often. Read data is 4-bytes aligned.
            glReadPixels(X, Y, w, h, mReadFormat, mReadType, pixels);

            // blur that texture.
            GGLSurface bl;
            bl.version = sizeof(GGLSurface);
            bl.width = w;
            bl.height = h;
            bl.stride = s;
            bl.format = mBlurFormat;
            bl.data = (GGLubyte*)pixels;            
            blurFilter(&bl, 8, 2);

            if (GLExtensions::getInstance().haveNpot()) {
                glTexImage2D(GL_TEXTURE_2D, 0, mReadFormat, w, h, 0,
                        mReadFormat, mReadType, pixels);
                mWidthScale  = 1.0f / w;
                mHeightScale =-1.0f / h;
                mYOffset = 0;
            } else {
                GLuint tw = 1 << (31 - clz(w));
                GLuint th = 1 << (31 - clz(h));
                if (tw < GLuint(w)) tw <<= 1;
                if (th < GLuint(h)) th <<= 1;
                glTexImage2D(GL_TEXTURE_2D, 0, mReadFormat, tw, th, 0,
                        mReadFormat, mReadType, NULL);
                glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, w, h, 
                        mReadFormat, mReadType, pixels);
                mWidthScale  = 1.0f / tw;
                mHeightScale =-1.0f / th;
                mYOffset = th-h;
            }

            free((void*)pixels);
        }

        const State& s = drawingState();
        if (UNLIKELY(s.alpha < 0xFF)) {
            const GLfloat alpha = s.alpha * (1.0f/255.0f);
            glColor4f(0, 0, 0, alpha);
            glEnable(GL_BLEND);
            glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
            glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
        } else {
            glDisable(GL_BLEND);
        }

        if (mFlags & DisplayHardware::SLOW_CONFIG) {
            glDisable(GL_DITHER);
        } else {
            glEnable(GL_DITHER);
        }

        glTexEnvx(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
        glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
        glTexParameterx(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);

#ifdef AVOID_DRAW_TEXTURE
        if(UNLIKELY(transformed()))
#endif
        {
            glMatrixMode(GL_TEXTURE);
            glLoadIdentity();
            glScalef(mWidthScale, mHeightScale, 1);
            glTranslatef(-x, mYOffset - y, 0);
            glEnableClientState(GL_TEXTURE_COORD_ARRAY);
            glVertexPointer(2, GL_FLOAT, 0, mVertices);
            glTexCoordPointer(2, GL_FLOAT, 0, mVertices);
            while (it != end) {
                const Rect& r = *it++;
                const GLint sy = fbHeight - (r.top + r.height());
                glScissor(r.left, sy, r.width(), r.height());
                glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
            }
            glDisableClientState(GL_TEXTURE_COORD_ARRAY);
        }
#ifdef AVOID_DRAW_TEXTURE
        else{
            Rect r;
            GLint crop[4] = { 0, 0, w, h };
            glTexParameteriv(GL_TEXTURE_2D, GL_TEXTURE_CROP_RECT_OES, crop);
            y = fbHeight - (y + h);
            while (it != end) {
                const Rect& r = *it++;
                const GLint sy = fbHeight - (r.top + r.height());
                glScissor(r.left, sy, r.width(), r.height());
                glDrawTexiOES(x, y, 0, w, h);
            }
        }
#endif
        glLoadIdentity();
        glMatrixMode(GL_MODELVIEW);
    }
}
Ejemplo n.º 30
0
// Find last bit set. The integral part of log2(n).
inline uintptr_t fls(uintptr_t n){
  return (uintptr_t) bitcnt() - clz(n);
}