1ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com 2ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com/* 3ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * Copyright 2006 The Android Open Source Project 4ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * 5ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * Use of this source code is governed by a BSD-style license that can be 6ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * found in the LICENSE file. 7ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com */ 8ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com 98a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#ifndef SkRegionPriv_DEFINED 118a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#define SkRegionPriv_DEFINED 128a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 138a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkRegion.h" 148a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkThread.h" 158a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 168a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#define assert_sentinel(value, isSentinel) \ 178a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(((value) == SkRegion::kRunTypeSentinel) == isSentinel) 188a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 198a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com//SkDEBUGCODE(extern int32_t gRgnAllocCounter;) 208a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 219c36a76102453db964cb6e51078a3d74d4126b2creed@google.com#ifdef SK_DEBUG 229c36a76102453db964cb6e51078a3d74d4126b2creed@google.com// Given the first interval (just past the interval-count), compute the 239c36a76102453db964cb6e51078a3d74d4126b2creed@google.com// interval count, by search for the x-sentinel 249c36a76102453db964cb6e51078a3d74d4126b2creed@google.com// 259c36a76102453db964cb6e51078a3d74d4126b2creed@google.comstatic int compute_intervalcount(const SkRegion::RunType runs[]) { 269c36a76102453db964cb6e51078a3d74d4126b2creed@google.com const SkRegion::RunType* curr = runs; 279c36a76102453db964cb6e51078a3d74d4126b2creed@google.com while (*curr < SkRegion::kRunTypeSentinel) { 289c36a76102453db964cb6e51078a3d74d4126b2creed@google.com SkASSERT(curr[0] < curr[1]); 299c36a76102453db964cb6e51078a3d74d4126b2creed@google.com SkASSERT(curr[1] < SkRegion::kRunTypeSentinel); 309c36a76102453db964cb6e51078a3d74d4126b2creed@google.com curr += 2; 319c36a76102453db964cb6e51078a3d74d4126b2creed@google.com } 32f117781362ecf673f43f93918781853690f0e145commit-bot@chromium.org return SkToInt((curr - runs) >> 1); 339c36a76102453db964cb6e51078a3d74d4126b2creed@google.com} 349c36a76102453db964cb6e51078a3d74d4126b2creed@google.com#endif 359c36a76102453db964cb6e51078a3d74d4126b2creed@google.com 368a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comstruct SkRegion::RunHead { 379c36a76102453db964cb6e51078a3d74d4126b2creed@google.comprivate: 389c36a76102453db964cb6e51078a3d74d4126b2creed@google.com 399c36a76102453db964cb6e51078a3d74d4126b2creed@google.compublic: 408a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com int32_t fRefCnt; 418a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com int32_t fRunCount; 42fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com 43af7e6943b74260ff9038bfbe0f8c50cf66657e83reed@google.com /** 44af7e6943b74260ff9038bfbe0f8c50cf66657e83reed@google.com * Number of spans with different Y values. This does not count the initial 45af7e6943b74260ff9038bfbe0f8c50cf66657e83reed@google.com * Top value, nor does it count the final Y-Sentinel value. In the logical 46af7e6943b74260ff9038bfbe0f8c50cf66657e83reed@google.com * case of a rectangle, this would return 1, and an empty region would 47af7e6943b74260ff9038bfbe0f8c50cf66657e83reed@google.com * return 0. 48af7e6943b74260ff9038bfbe0f8c50cf66657e83reed@google.com */ 49af7e6943b74260ff9038bfbe0f8c50cf66657e83reed@google.com int getYSpanCount() const { 50af7e6943b74260ff9038bfbe0f8c50cf66657e83reed@google.com return fYSpanCount; 51af7e6943b74260ff9038bfbe0f8c50cf66657e83reed@google.com } 52af7e6943b74260ff9038bfbe0f8c50cf66657e83reed@google.com 53af7e6943b74260ff9038bfbe0f8c50cf66657e83reed@google.com /** 54af7e6943b74260ff9038bfbe0f8c50cf66657e83reed@google.com * Number of intervals in the entire region. This equals the number of 55af7e6943b74260ff9038bfbe0f8c50cf66657e83reed@google.com * rects that would be returned by the Iterator. In the logical case of 56af7e6943b74260ff9038bfbe0f8c50cf66657e83reed@google.com * a rect, this would return 1, and an empty region would return 0. 57af7e6943b74260ff9038bfbe0f8c50cf66657e83reed@google.com */ 58af7e6943b74260ff9038bfbe0f8c50cf66657e83reed@google.com int getIntervalCount() const { 59af7e6943b74260ff9038bfbe0f8c50cf66657e83reed@google.com return fIntervalCount; 60af7e6943b74260ff9038bfbe0f8c50cf66657e83reed@google.com } 61af7e6943b74260ff9038bfbe0f8c50cf66657e83reed@google.com 62a95ea2c518577a6696dc0b786ad3aaf7315af850reed@google.com static RunHead* Alloc(int count) { 638a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com //SkDEBUGCODE(sk_atomic_inc(&gRgnAllocCounter);) 648a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com //SkDEBUGF(("************** gRgnAllocCounter::alloc %d\n", gRgnAllocCounter)); 65fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com 668a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(count >= SkRegion::kRectRegionRuns); 67fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com 688a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com RunHead* head = (RunHead*)sk_malloc_throw(sizeof(RunHead) + count * sizeof(RunType)); 698a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com head->fRefCnt = 1; 708a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com head->fRunCount = count; 71af7e6943b74260ff9038bfbe0f8c50cf66657e83reed@google.com // these must be filled in later, otherwise we will be invalid 72af7e6943b74260ff9038bfbe0f8c50cf66657e83reed@google.com head->fYSpanCount = 0; 73af7e6943b74260ff9038bfbe0f8c50cf66657e83reed@google.com head->fIntervalCount = 0; 74af7e6943b74260ff9038bfbe0f8c50cf66657e83reed@google.com return head; 75af7e6943b74260ff9038bfbe0f8c50cf66657e83reed@google.com } 76fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com 77af7e6943b74260ff9038bfbe0f8c50cf66657e83reed@google.com static RunHead* Alloc(int count, int yspancount, int intervalCount) { 78af7e6943b74260ff9038bfbe0f8c50cf66657e83reed@google.com SkASSERT(yspancount > 0); 79af7e6943b74260ff9038bfbe0f8c50cf66657e83reed@google.com SkASSERT(intervalCount > 1); 80af7e6943b74260ff9038bfbe0f8c50cf66657e83reed@google.com 81af7e6943b74260ff9038bfbe0f8c50cf66657e83reed@google.com RunHead* head = Alloc(count); 82af7e6943b74260ff9038bfbe0f8c50cf66657e83reed@google.com head->fYSpanCount = yspancount; 83af7e6943b74260ff9038bfbe0f8c50cf66657e83reed@google.com head->fIntervalCount = intervalCount; 848a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return head; 858a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 86fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com 87a95ea2c518577a6696dc0b786ad3aaf7315af850reed@google.com SkRegion::RunType* writable_runs() { 888a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(fRefCnt == 1); 898a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return (SkRegion::RunType*)(this + 1); 908a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 91a95ea2c518577a6696dc0b786ad3aaf7315af850reed@google.com 92a95ea2c518577a6696dc0b786ad3aaf7315af850reed@google.com const SkRegion::RunType* readonly_runs() const { 938a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return (const SkRegion::RunType*)(this + 1); 948a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 95fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com 96a95ea2c518577a6696dc0b786ad3aaf7315af850reed@google.com RunHead* ensureWritable() { 978a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com RunHead* writable = this; 98a95ea2c518577a6696dc0b786ad3aaf7315af850reed@google.com if (fRefCnt > 1) { 998a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // We need to alloc & copy the current region before we call 1008a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // sk_atomic_dec because it could be freed in the meantime, 101fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com // otherwise. 102af7e6943b74260ff9038bfbe0f8c50cf66657e83reed@google.com writable = Alloc(fRunCount, fYSpanCount, fIntervalCount); 1038a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com memcpy(writable->writable_runs(), this->readonly_runs(), 1048a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fRunCount * sizeof(RunType)); 1058a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1068a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // fRefCount might have changed since we last checked. 1078a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // If we own the last reference at this point, we need to 1088a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // free the memory. 109a95ea2c518577a6696dc0b786ad3aaf7315af850reed@google.com if (sk_atomic_dec(&fRefCnt) == 1) { 1108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com sk_free(this); 1118a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 1128a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 1138a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return writable; 1148a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 115fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com 1169c36a76102453db964cb6e51078a3d74d4126b2creed@google.com /** 1179c36a76102453db964cb6e51078a3d74d4126b2creed@google.com * Given a scanline (including its Bottom value at runs[0]), return the next 1189c36a76102453db964cb6e51078a3d74d4126b2creed@google.com * scanline. Asserts that there is one (i.e. runs[0] < Sentinel) 1199c36a76102453db964cb6e51078a3d74d4126b2creed@google.com */ 1209c36a76102453db964cb6e51078a3d74d4126b2creed@google.com static SkRegion::RunType* SkipEntireScanline(const SkRegion::RunType runs[]) { 1219c36a76102453db964cb6e51078a3d74d4126b2creed@google.com // we are not the Y Sentinel 1229c36a76102453db964cb6e51078a3d74d4126b2creed@google.com SkASSERT(runs[0] < SkRegion::kRunTypeSentinel); 123fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com 1249c36a76102453db964cb6e51078a3d74d4126b2creed@google.com const int intervals = runs[1]; 1259c36a76102453db964cb6e51078a3d74d4126b2creed@google.com SkASSERT(runs[2 + intervals * 2] == SkRegion::kRunTypeSentinel); 1269c36a76102453db964cb6e51078a3d74d4126b2creed@google.com#ifdef SK_DEBUG 1279c36a76102453db964cb6e51078a3d74d4126b2creed@google.com { 1289c36a76102453db964cb6e51078a3d74d4126b2creed@google.com int n = compute_intervalcount(&runs[2]); 1299c36a76102453db964cb6e51078a3d74d4126b2creed@google.com SkASSERT(n == intervals); 1309c36a76102453db964cb6e51078a3d74d4126b2creed@google.com } 1319c36a76102453db964cb6e51078a3d74d4126b2creed@google.com#endif 1329c36a76102453db964cb6e51078a3d74d4126b2creed@google.com 1339c36a76102453db964cb6e51078a3d74d4126b2creed@google.com // skip the entire line [B N [L R] S] 1349c36a76102453db964cb6e51078a3d74d4126b2creed@google.com runs += 1 + 1 + intervals * 2 + 1; 1359c36a76102453db964cb6e51078a3d74d4126b2creed@google.com return const_cast<SkRegion::RunType*>(runs); 1369c36a76102453db964cb6e51078a3d74d4126b2creed@google.com } 137fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com 138fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com 1399c36a76102453db964cb6e51078a3d74d4126b2creed@google.com /** 1409c36a76102453db964cb6e51078a3d74d4126b2creed@google.com * Return the scanline that contains the Y value. This requires that the Y 1419c36a76102453db964cb6e51078a3d74d4126b2creed@google.com * value is already known to be contained within the bounds of the region, 1429c36a76102453db964cb6e51078a3d74d4126b2creed@google.com * and so this routine never returns NULL. 1439c36a76102453db964cb6e51078a3d74d4126b2creed@google.com * 1449c36a76102453db964cb6e51078a3d74d4126b2creed@google.com * It returns the beginning of the scanline, starting with its Bottom value. 1459c36a76102453db964cb6e51078a3d74d4126b2creed@google.com */ 1469c36a76102453db964cb6e51078a3d74d4126b2creed@google.com SkRegion::RunType* findScanline(int y) const { 1479c36a76102453db964cb6e51078a3d74d4126b2creed@google.com const RunType* runs = this->readonly_runs(); 1489c36a76102453db964cb6e51078a3d74d4126b2creed@google.com 1499c36a76102453db964cb6e51078a3d74d4126b2creed@google.com // if the top-check fails, we didn't do a quick check on the bounds 1509c36a76102453db964cb6e51078a3d74d4126b2creed@google.com SkASSERT(y >= runs[0]); 151fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com 1529c36a76102453db964cb6e51078a3d74d4126b2creed@google.com runs += 1; // skip top-Y 1539c36a76102453db964cb6e51078a3d74d4126b2creed@google.com for (;;) { 1549c36a76102453db964cb6e51078a3d74d4126b2creed@google.com int bottom = runs[0]; 1559c36a76102453db964cb6e51078a3d74d4126b2creed@google.com // If we hit this, we've walked off the region, and our bounds check 1569c36a76102453db964cb6e51078a3d74d4126b2creed@google.com // failed. 1579c36a76102453db964cb6e51078a3d74d4126b2creed@google.com SkASSERT(bottom < SkRegion::kRunTypeSentinel); 1589c36a76102453db964cb6e51078a3d74d4126b2creed@google.com if (y < bottom) { 1599c36a76102453db964cb6e51078a3d74d4126b2creed@google.com break; 1609c36a76102453db964cb6e51078a3d74d4126b2creed@google.com } 1619c36a76102453db964cb6e51078a3d74d4126b2creed@google.com runs = SkipEntireScanline(runs); 1629c36a76102453db964cb6e51078a3d74d4126b2creed@google.com } 1639c36a76102453db964cb6e51078a3d74d4126b2creed@google.com return const_cast<SkRegion::RunType*>(runs); 1649c36a76102453db964cb6e51078a3d74d4126b2creed@google.com } 1659c36a76102453db964cb6e51078a3d74d4126b2creed@google.com 1669c36a76102453db964cb6e51078a3d74d4126b2creed@google.com // Copy src runs into us, computing interval counts and bounds along the way 1679c36a76102453db964cb6e51078a3d74d4126b2creed@google.com void computeRunBounds(SkIRect* bounds) { 1689c36a76102453db964cb6e51078a3d74d4126b2creed@google.com RunType* runs = this->writable_runs(); 1699c36a76102453db964cb6e51078a3d74d4126b2creed@google.com bounds->fTop = *runs++; 170fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com 1719c36a76102453db964cb6e51078a3d74d4126b2creed@google.com int bot; 1729c36a76102453db964cb6e51078a3d74d4126b2creed@google.com int ySpanCount = 0; 1739c36a76102453db964cb6e51078a3d74d4126b2creed@google.com int intervalCount = 0; 1749c36a76102453db964cb6e51078a3d74d4126b2creed@google.com int left = SK_MaxS32; 1759c36a76102453db964cb6e51078a3d74d4126b2creed@google.com int rite = SK_MinS32; 1769c36a76102453db964cb6e51078a3d74d4126b2creed@google.com 1779c36a76102453db964cb6e51078a3d74d4126b2creed@google.com do { 1789c36a76102453db964cb6e51078a3d74d4126b2creed@google.com bot = *runs++; 1799c36a76102453db964cb6e51078a3d74d4126b2creed@google.com SkASSERT(bot < SkRegion::kRunTypeSentinel); 1809c36a76102453db964cb6e51078a3d74d4126b2creed@google.com ySpanCount += 1; 181fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com 1829c36a76102453db964cb6e51078a3d74d4126b2creed@google.com const int intervals = *runs++; 1839c36a76102453db964cb6e51078a3d74d4126b2creed@google.com SkASSERT(intervals >= 0); 1849c36a76102453db964cb6e51078a3d74d4126b2creed@google.com SkASSERT(intervals < SkRegion::kRunTypeSentinel); 1859c36a76102453db964cb6e51078a3d74d4126b2creed@google.com 1869c36a76102453db964cb6e51078a3d74d4126b2creed@google.com if (intervals > 0) { 1879c36a76102453db964cb6e51078a3d74d4126b2creed@google.com#ifdef SK_DEBUG 1889c36a76102453db964cb6e51078a3d74d4126b2creed@google.com { 1899c36a76102453db964cb6e51078a3d74d4126b2creed@google.com int n = compute_intervalcount(runs); 1909c36a76102453db964cb6e51078a3d74d4126b2creed@google.com SkASSERT(n == intervals); 1919c36a76102453db964cb6e51078a3d74d4126b2creed@google.com } 1929c36a76102453db964cb6e51078a3d74d4126b2creed@google.com#endif 1939c36a76102453db964cb6e51078a3d74d4126b2creed@google.com RunType L = runs[0]; 1949c36a76102453db964cb6e51078a3d74d4126b2creed@google.com SkASSERT(L < SkRegion::kRunTypeSentinel); 1959c36a76102453db964cb6e51078a3d74d4126b2creed@google.com if (left > L) { 1969c36a76102453db964cb6e51078a3d74d4126b2creed@google.com left = L; 1979c36a76102453db964cb6e51078a3d74d4126b2creed@google.com } 198fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com 1999c36a76102453db964cb6e51078a3d74d4126b2creed@google.com runs += intervals * 2; 2009c36a76102453db964cb6e51078a3d74d4126b2creed@google.com RunType R = runs[-1]; 2019c36a76102453db964cb6e51078a3d74d4126b2creed@google.com SkASSERT(R < SkRegion::kRunTypeSentinel); 2029c36a76102453db964cb6e51078a3d74d4126b2creed@google.com if (rite < R) { 2039c36a76102453db964cb6e51078a3d74d4126b2creed@google.com rite = R; 2049c36a76102453db964cb6e51078a3d74d4126b2creed@google.com } 205fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com 2069c36a76102453db964cb6e51078a3d74d4126b2creed@google.com intervalCount += intervals; 2079c36a76102453db964cb6e51078a3d74d4126b2creed@google.com } 2089c36a76102453db964cb6e51078a3d74d4126b2creed@google.com SkASSERT(SkRegion::kRunTypeSentinel == *runs); 2099c36a76102453db964cb6e51078a3d74d4126b2creed@google.com runs += 1; // skip x-sentinel 2109c36a76102453db964cb6e51078a3d74d4126b2creed@google.com 2119c36a76102453db964cb6e51078a3d74d4126b2creed@google.com // test Y-sentinel 2129c36a76102453db964cb6e51078a3d74d4126b2creed@google.com } while (SkRegion::kRunTypeSentinel > *runs); 213fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com 2149c36a76102453db964cb6e51078a3d74d4126b2creed@google.com#ifdef SK_DEBUG 2159c36a76102453db964cb6e51078a3d74d4126b2creed@google.com // +1 to skip the last Y-sentinel 216f117781362ecf673f43f93918781853690f0e145commit-bot@chromium.org int runCount = SkToInt(runs - this->writable_runs() + 1); 2179c36a76102453db964cb6e51078a3d74d4126b2creed@google.com SkASSERT(runCount == fRunCount); 2189c36a76102453db964cb6e51078a3d74d4126b2creed@google.com#endif 219fbfcd5602128ec010c82cb733c9cdc0a3254f9f3rmistry@google.com 2209c36a76102453db964cb6e51078a3d74d4126b2creed@google.com fYSpanCount = ySpanCount; 2219c36a76102453db964cb6e51078a3d74d4126b2creed@google.com fIntervalCount = intervalCount; 2229c36a76102453db964cb6e51078a3d74d4126b2creed@google.com 2239c36a76102453db964cb6e51078a3d74d4126b2creed@google.com bounds->fLeft = left; 2249c36a76102453db964cb6e51078a3d74d4126b2creed@google.com bounds->fRight = rite; 2259c36a76102453db964cb6e51078a3d74d4126b2creed@google.com bounds->fBottom = bot; 2269c36a76102453db964cb6e51078a3d74d4126b2creed@google.com } 227af7e6943b74260ff9038bfbe0f8c50cf66657e83reed@google.com 228af7e6943b74260ff9038bfbe0f8c50cf66657e83reed@google.comprivate: 229af7e6943b74260ff9038bfbe0f8c50cf66657e83reed@google.com int32_t fYSpanCount; 230af7e6943b74260ff9038bfbe0f8c50cf66657e83reed@google.com int32_t fIntervalCount; 2318a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}; 2328a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2338a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#endif 234