gfx/skia/trunk/src/ports/SkPurgeableMemoryBlock_mac.cpp

changeset 0
6474c204b198
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/gfx/skia/trunk/src/ports/SkPurgeableMemoryBlock_mac.cpp	Wed Dec 31 06:09:35 2014 +0100
     1.3 @@ -0,0 +1,104 @@
     1.4 +/*
     1.5 + * Copyright 2013 Google Inc.
     1.6 + *
     1.7 + * Use of this source code is governed by a BSD-style license that can be
     1.8 + * found in the LICENSE file.
     1.9 + */
    1.10 +
    1.11 +#include "SkPurgeableMemoryBlock.h"
    1.12 +
    1.13 +#include <mach/mach.h>
    1.14 +
    1.15 +bool SkPurgeableMemoryBlock::IsSupported() {
    1.16 +    return true;
    1.17 +}
    1.18 +
    1.19 +#ifdef SK_DEBUG
    1.20 +bool SkPurgeableMemoryBlock::PlatformSupportsPurgingAllUnpinnedBlocks() {
    1.21 +    return true;
    1.22 +}
    1.23 +
    1.24 +bool SkPurgeableMemoryBlock::PurgeAllUnpinnedBlocks() {
    1.25 +    // Unused.
    1.26 +    int state = 0;
    1.27 +    kern_return_t ret = vm_purgable_control(mach_task_self(), 0, VM_PURGABLE_PURGE_ALL, &state);
    1.28 +    return ret == KERN_SUCCESS;
    1.29 +}
    1.30 +
    1.31 +bool SkPurgeableMemoryBlock::purge() {
    1.32 +    return false;
    1.33 +}
    1.34 +#endif
    1.35 +
    1.36 +static size_t round_to_page_size(size_t size) {
    1.37 +    const size_t mask = 4096 - 1;
    1.38 +    return (size + mask) & ~mask;
    1.39 +}
    1.40 +
    1.41 +SkPurgeableMemoryBlock::SkPurgeableMemoryBlock(size_t size)
    1.42 +    : fAddr(NULL)
    1.43 +    , fSize(round_to_page_size(size))
    1.44 +    , fPinned(false) {
    1.45 +}
    1.46 +
    1.47 +SkPurgeableMemoryBlock::~SkPurgeableMemoryBlock() {
    1.48 +    SkDEBUGCODE(kern_return_t ret =) vm_deallocate(mach_task_self(),
    1.49 +                                                   reinterpret_cast<vm_address_t>(fAddr),
    1.50 +                                                   static_cast<vm_size_t>(fSize));
    1.51 +#ifdef SK_DEBUG
    1.52 +    if (ret != KERN_SUCCESS) {
    1.53 +        SkDebugf("SkPurgeableMemoryBlock destructor failed to deallocate.\n");
    1.54 +    }
    1.55 +#endif
    1.56 +}
    1.57 +
    1.58 +void* SkPurgeableMemoryBlock::pin(SkPurgeableMemoryBlock::PinResult* pinResult) {
    1.59 +    SkASSERT(!fPinned);
    1.60 +    SkASSERT(pinResult != NULL);
    1.61 +    if (NULL == fAddr) {
    1.62 +        vm_address_t addr = 0;
    1.63 +        kern_return_t ret = vm_allocate(mach_task_self(), &addr, static_cast<vm_size_t>(fSize),
    1.64 +                                        VM_FLAGS_PURGABLE | VM_FLAGS_ANYWHERE);
    1.65 +        if (KERN_SUCCESS == ret) {
    1.66 +            fAddr = reinterpret_cast<void*>(addr);
    1.67 +            *pinResult = kUninitialized_PinResult;
    1.68 +            fPinned = true;
    1.69 +        } else {
    1.70 +            fAddr = NULL;
    1.71 +        }
    1.72 +    } else {
    1.73 +        int state = VM_PURGABLE_NONVOLATILE;
    1.74 +        kern_return_t ret = vm_purgable_control(mach_task_self(),
    1.75 +                                                reinterpret_cast<vm_address_t>(fAddr),
    1.76 +                                                VM_PURGABLE_SET_STATE, &state);
    1.77 +        if (ret != KERN_SUCCESS) {
    1.78 +            fAddr = NULL;
    1.79 +            fPinned = false;
    1.80 +            return NULL;
    1.81 +        }
    1.82 +
    1.83 +        fPinned = true;
    1.84 +
    1.85 +        if (state & VM_PURGABLE_EMPTY) {
    1.86 +            *pinResult = kUninitialized_PinResult;
    1.87 +        } else {
    1.88 +            *pinResult = kRetained_PinResult;
    1.89 +        }
    1.90 +    }
    1.91 +    return fAddr;
    1.92 +}
    1.93 +
    1.94 +void SkPurgeableMemoryBlock::unpin() {
    1.95 +    SkASSERT(fPinned);
    1.96 +    int state = VM_PURGABLE_VOLATILE | VM_VOLATILE_GROUP_DEFAULT;
    1.97 +    SkDEBUGCODE(kern_return_t ret =) vm_purgable_control(mach_task_self(),
    1.98 +                                                         reinterpret_cast<vm_address_t>(fAddr),
    1.99 +                                                         VM_PURGABLE_SET_STATE, &state);
   1.100 +    fPinned = false;
   1.101 +
   1.102 +#ifdef SK_DEBUG
   1.103 +    if (ret != KERN_SUCCESS) {
   1.104 +        SkDebugf("SkPurgeableMemoryBlock::unpin() failed.\n");
   1.105 +    }
   1.106 +#endif
   1.107 +}

mercurial