Example #1
0
int gpu_context_t::gralloc_alloc_buffer(size_t size, int usage, buffer_handle_t* pHandle)
{
    int err = 0;
    int flags = 0;

    int fd = -1;
    void* base = 0; // XXX JMG: This should change to just get an address from
                    // the PmemAllocator rather than getting the base & offset separately
    int offset = 0;
    int lockState = 0;

    size = roundUpToPageSize(size);
#ifndef USE_ASHMEM
    if (usage & GRALLOC_USAGE_HW_TEXTURE) {
        // enable pmem in that case, so our software GL can fallback to
        // the copybit module.
        flags |= private_handle_t::PRIV_FLAGS_USES_PMEM;
    }

    if (usage & GRALLOC_USAGE_HW_2D) {
        flags |= private_handle_t::PRIV_FLAGS_USES_PMEM;
    }
#else
    if (usage & GRALLOC_USAGE_PRIVATE_PMEM){
        flags |= private_handle_t::PRIV_FLAGS_USES_PMEM;
    }
#endif
    if (usage & GRALLOC_USAGE_PRIVATE_PMEM_ADSP) {
        flags |= private_handle_t::PRIV_FLAGS_USES_PMEM_ADSP;
        flags &= ~private_handle_t::PRIV_FLAGS_USES_PMEM;
    }

    private_module_t* m = reinterpret_cast<private_module_t*>(common.module);
    if((flags & private_handle_t::PRIV_FLAGS_USES_PMEM) == 0 &&
       (flags & private_handle_t::PRIV_FLAGS_USES_PMEM_ADSP) == 0) {
       flags |= private_handle_t::PRIV_FLAGS_USES_ASHMEM;
       err = alloc_ashmem_buffer(size, (unsigned int)pHandle, &base, &offset, &fd);
       if(err >= 0)
            lockState |= private_handle_t::LOCK_STATE_MAPPED; 
    }
    else if ((flags & private_handle_t::PRIV_FLAGS_USES_PMEM) != 0 ||
        (flags & private_handle_t::PRIV_FLAGS_USES_PMEM_ADSP) != 0) {

        PmemAllocator* pma = 0;

        if ((flags & private_handle_t::PRIV_FLAGS_USES_PMEM) != 0) {
          if ((flags & private_handle_t::PRIV_FLAGS_USES_PMEM_ADSP) != 0) {
              LOGE("attempting to allocate a gralloc buffer with both the "
                   "USES_PMEM and USES_PMEM_ADSP flags.  Unsetting the "
                   "USES_PMEM_ADSP flag.");
              flags &= ~private_handle_t::PRIV_FLAGS_USES_PMEM_ADSP;
          }
          pma = &pmemAllocator;
        } else { // (flags & private_handle_t::PRIV_FLAGS_USES_PMEM_ADSP) != 0
          pma = &pmemAdspAllocator;
        }

        // PMEM buffers are always mmapped
        lockState |= private_handle_t::LOCK_STATE_MAPPED;

        // Allocate the buffer from pmem
        err = pma->alloc_pmem_buffer(size, usage, &base, &offset, &fd);
        if (err < 0) {
            if (((usage & GRALLOC_USAGE_HW_MASK) == 0) &&
                ((usage & GRALLOC_USAGE_PRIVATE_PMEM_ADSP) == 0)) {
                // the caller didn't request PMEM, so we can try something else
                flags &= ~private_handle_t::PRIV_FLAGS_USES_PMEM;
                err = 0;
                goto try_ashmem;
            } else {
                LOGE("couldn't open pmem (%s)", strerror(errno));
            }
        }
    } else {
try_ashmem:
        fd = deps.ashmem_create_region("gralloc-buffer", size);
        if (fd < 0) {
            LOGE("couldn't create ashmem (%s)", strerror(errno));
            err = -errno;
        }
    }

    if (err == 0) {
        private_handle_t* hnd = new private_handle_t(fd, size, flags);
        hnd->offset = offset;
        hnd->base = int(base)+offset;
        hnd->lockState = lockState;
        *pHandle = hnd;
    }

    LOGE_IF(err, "gralloc failed err=%s", strerror(-err));

    return err;
}
Example #2
0
int gpu_context_t::gralloc_alloc_buffer(size_t size, int usage, buffer_handle_t* pHandle,
                                        int bufferType, int format, int width, int height)
{
    int err = 0;
    int flags = 0;

    int fd = -1;
    void* base = 0; // XXX JMG: This should change to just get an address from
                    // the PmemAllocator rather than getting the base & offset separately
    int offset = 0;
    int lockState = 0;

    size = roundUpToPageSize(size);
#ifndef USE_ASHMEM
    if (usage & GRALLOC_USAGE_HW_TEXTURE) {
        // enable pmem in that case, so our software GL can fallback to
        // the copybit module.
        flags |= private_handle_t::PRIV_FLAGS_USES_PMEM;
    }

    if (usage & GRALLOC_USAGE_HW_2D) {
        flags |= private_handle_t::PRIV_FLAGS_USES_PMEM;
    }
#else
    // Enable use of PMEM only when MDP composition is used (and other conditions apply).
    // Else fall back on using ASHMEM
    if ((get_composition_type() == MDP_COMPOSITION) &&
        ((usage & GRALLOC_USAGE_HW_TEXTURE) || (usage & GRALLOC_USAGE_HW_2D)) ) {
        flags |= private_handle_t::PRIV_FLAGS_USES_PMEM;
    }

    if (usage & GRALLOC_USAGE_PRIVATE_PMEM) {
        flags |= private_handle_t::PRIV_FLAGS_USES_PMEM;
    }
#endif
    if ((usage & GRALLOC_USAGE_PRIVATE_PMEM_ADSP) || (usage & GRALLOC_USAGE_PRIVATE_PMEM_SMIPOOL)
        || (usage & GRALLOC_USAGE_EXTERNAL_DISP) || (usage & GRALLOC_USAGE_PROTECTED)) {
        flags |= private_handle_t::PRIV_FLAGS_USES_PMEM_ADSP;
        flags &= ~private_handle_t::PRIV_FLAGS_USES_PMEM;
    }

    private_module_t* m = reinterpret_cast<private_module_t*>(common.module);
    if((flags & private_handle_t::PRIV_FLAGS_USES_PMEM) == 0 &&
       (flags & private_handle_t::PRIV_FLAGS_USES_PMEM_ADSP) == 0) {
       flags |= private_handle_t::PRIV_FLAGS_USES_ASHMEM;
       err = alloc_ashmem_buffer(size, (unsigned int)pHandle, &base, &offset, &fd);
       if(err >= 0)
            lockState |= private_handle_t::LOCK_STATE_MAPPED; 
    }
    else if ((flags & private_handle_t::PRIV_FLAGS_USES_PMEM) != 0 ||
        (flags & private_handle_t::PRIV_FLAGS_USES_PMEM_ADSP) != 0) {

        PmemAllocator* pma = 0;

        if ((flags & private_handle_t::PRIV_FLAGS_USES_PMEM) != 0) {
          if ((flags & private_handle_t::PRIV_FLAGS_USES_PMEM_ADSP) != 0) {
              LOGE("attempting to allocate a gralloc buffer with both the "
                   "USES_PMEM and USES_PMEM_ADSP flags.  Unsetting the "
                   "USES_PMEM_ADSP flag.");
              flags &= ~private_handle_t::PRIV_FLAGS_USES_PMEM_ADSP;
          }
          pma = &pmemAllocator;
        } else { // (flags & private_handle_t::PRIV_FLAGS_USES_PMEM_ADSP) != 0
          pma = &pmemAdspAllocator;
        }

        // PMEM buffers are always mmapped
        lockState |= private_handle_t::LOCK_STATE_MAPPED;

        err = pma->alloc_pmem_buffer(size, usage, &base, &offset, &fd, format);
        if (err < 0) {
            // Pmem allocation failed. Try falling back to ashmem iff we are:
            // a. not using MDP composition
            // b. not allocating memory for a buffer to be used by overlays
            // c. The client has not explicitly requested a PMEM buffer
            if ((get_composition_type() != MDP_COMPOSITION) &&
                (bufferType != BUFFER_TYPE_VIDEO) &&
                ((usage & GRALLOC_USAGE_PRIVATE_PMEM) == 0) &&
                ((usage & GRALLOC_USAGE_PRIVATE_PMEM_ADSP) == 0)) {
                // the caller didn't request PMEM, so we can try something else
                flags &= ~private_handle_t::PRIV_FLAGS_USES_PMEM;
                err = 0;
                LOGE("Pmem allocation failed. Trying ashmem");
                goto try_ashmem;
            } else {
                LOGE("couldn't open pmem (%s)", strerror(errno));
            }
        }
    } else {
try_ashmem:
        err = alloc_ashmem_buffer(size, (unsigned int)pHandle, &base, &offset, &fd);
        if (err >= 0) {
            lockState |= private_handle_t::LOCK_STATE_MAPPED;
            flags |= private_handle_t::PRIV_FLAGS_USES_ASHMEM;
        } else {
            LOGE("Ashmem fallback failed");
        }
    }

    if (err == 0) {
        private_handle_t* hnd = new private_handle_t(fd, size, flags, bufferType, format, width, height);
        hnd->offset = offset;
        hnd->base = int(base)+offset;
        hnd->lockState = lockState;
        *pHandle = hnd;
    }

    LOGE_IF(err, "gralloc failed err=%s", strerror(-err));

    return err;
}