Sat, 03 Jan 2015 20:18:00 +0100
Conditionally enable double key logic according to:
private browsing mode or privacy.thirdparty.isolate preference and
implement in GetCookieStringCommon and FindCookie where it counts...
With some reservations of how to convince FindCookie users to test
condition and pass a nullptr when disabling double key logic.
michael@0 | 1 | /* |
michael@0 | 2 | * Copyright 2013 Google Inc. |
michael@0 | 3 | * |
michael@0 | 4 | * Use of this source code is governed by a BSD-style license that can be |
michael@0 | 5 | * found in the LICENSE file. |
michael@0 | 6 | */ |
michael@0 | 7 | |
michael@0 | 8 | #include "GrGLBufferImpl.h" |
michael@0 | 9 | #include "GrGpuGL.h" |
michael@0 | 10 | |
michael@0 | 11 | #define GL_CALL(GPU, X) GR_GL_CALL(GPU->glInterface(), X) |
michael@0 | 12 | |
michael@0 | 13 | #ifdef SK_DEBUG |
michael@0 | 14 | #define VALIDATE() this->validate() |
michael@0 | 15 | #else |
michael@0 | 16 | #define VALIDATE() do {} while(false) |
michael@0 | 17 | #endif |
michael@0 | 18 | |
michael@0 | 19 | // GL_STREAM_DRAW triggers an optimization in Chromium's GPU process where a client's vertex buffer |
michael@0 | 20 | // objects are implemented as client-side-arrays on tile-deferred architectures. |
michael@0 | 21 | #define DYNAMIC_USAGE_PARAM GR_GL_STREAM_DRAW |
michael@0 | 22 | |
michael@0 | 23 | GrGLBufferImpl::GrGLBufferImpl(GrGpuGL* gpu, const Desc& desc, GrGLenum bufferType) |
michael@0 | 24 | : fDesc(desc) |
michael@0 | 25 | , fBufferType(bufferType) |
michael@0 | 26 | , fLockPtr(NULL) { |
michael@0 | 27 | if (0 == desc.fID) { |
michael@0 | 28 | fCPUData = sk_malloc_flags(desc.fSizeInBytes, SK_MALLOC_THROW); |
michael@0 | 29 | } else { |
michael@0 | 30 | fCPUData = NULL; |
michael@0 | 31 | } |
michael@0 | 32 | VALIDATE(); |
michael@0 | 33 | } |
michael@0 | 34 | |
michael@0 | 35 | void GrGLBufferImpl::release(GrGpuGL* gpu) { |
michael@0 | 36 | // make sure we've not been abandoned or already released |
michael@0 | 37 | if (NULL != fCPUData) { |
michael@0 | 38 | VALIDATE(); |
michael@0 | 39 | sk_free(fCPUData); |
michael@0 | 40 | fCPUData = NULL; |
michael@0 | 41 | } else if (fDesc.fID && !fDesc.fIsWrapped) { |
michael@0 | 42 | VALIDATE(); |
michael@0 | 43 | GL_CALL(gpu, DeleteBuffers(1, &fDesc.fID)); |
michael@0 | 44 | if (GR_GL_ARRAY_BUFFER == fBufferType) { |
michael@0 | 45 | gpu->notifyVertexBufferDelete(fDesc.fID); |
michael@0 | 46 | } else { |
michael@0 | 47 | SkASSERT(GR_GL_ELEMENT_ARRAY_BUFFER == fBufferType); |
michael@0 | 48 | gpu->notifyIndexBufferDelete(fDesc.fID); |
michael@0 | 49 | } |
michael@0 | 50 | fDesc.fID = 0; |
michael@0 | 51 | } |
michael@0 | 52 | fLockPtr = NULL; |
michael@0 | 53 | } |
michael@0 | 54 | |
michael@0 | 55 | void GrGLBufferImpl::abandon() { |
michael@0 | 56 | fDesc.fID = 0; |
michael@0 | 57 | fLockPtr = NULL; |
michael@0 | 58 | sk_free(fCPUData); |
michael@0 | 59 | fCPUData = NULL; |
michael@0 | 60 | } |
michael@0 | 61 | |
michael@0 | 62 | void GrGLBufferImpl::bind(GrGpuGL* gpu) const { |
michael@0 | 63 | VALIDATE(); |
michael@0 | 64 | if (GR_GL_ARRAY_BUFFER == fBufferType) { |
michael@0 | 65 | gpu->bindVertexBuffer(fDesc.fID); |
michael@0 | 66 | } else { |
michael@0 | 67 | SkASSERT(GR_GL_ELEMENT_ARRAY_BUFFER == fBufferType); |
michael@0 | 68 | gpu->bindIndexBufferAndDefaultVertexArray(fDesc.fID); |
michael@0 | 69 | } |
michael@0 | 70 | } |
michael@0 | 71 | |
michael@0 | 72 | void* GrGLBufferImpl::lock(GrGpuGL* gpu) { |
michael@0 | 73 | VALIDATE(); |
michael@0 | 74 | SkASSERT(!this->isLocked()); |
michael@0 | 75 | if (0 == fDesc.fID) { |
michael@0 | 76 | fLockPtr = fCPUData; |
michael@0 | 77 | } else if (gpu->caps()->bufferLockSupport()) { |
michael@0 | 78 | this->bind(gpu); |
michael@0 | 79 | // Let driver know it can discard the old data |
michael@0 | 80 | GL_CALL(gpu, BufferData(fBufferType, |
michael@0 | 81 | (GrGLsizeiptr) fDesc.fSizeInBytes, |
michael@0 | 82 | NULL, |
michael@0 | 83 | fDesc.fDynamic ? DYNAMIC_USAGE_PARAM : GR_GL_STATIC_DRAW)); |
michael@0 | 84 | GR_GL_CALL_RET(gpu->glInterface(), |
michael@0 | 85 | fLockPtr, |
michael@0 | 86 | MapBuffer(fBufferType, GR_GL_WRITE_ONLY)); |
michael@0 | 87 | } |
michael@0 | 88 | return fLockPtr; |
michael@0 | 89 | } |
michael@0 | 90 | |
michael@0 | 91 | void GrGLBufferImpl::unlock(GrGpuGL* gpu) { |
michael@0 | 92 | VALIDATE(); |
michael@0 | 93 | SkASSERT(this->isLocked()); |
michael@0 | 94 | if (0 != fDesc.fID) { |
michael@0 | 95 | SkASSERT(gpu->caps()->bufferLockSupport()); |
michael@0 | 96 | this->bind(gpu); |
michael@0 | 97 | GL_CALL(gpu, UnmapBuffer(fBufferType)); |
michael@0 | 98 | } |
michael@0 | 99 | fLockPtr = NULL; |
michael@0 | 100 | } |
michael@0 | 101 | |
michael@0 | 102 | bool GrGLBufferImpl::isLocked() const { |
michael@0 | 103 | VALIDATE(); |
michael@0 | 104 | return NULL != fLockPtr; |
michael@0 | 105 | } |
michael@0 | 106 | |
michael@0 | 107 | bool GrGLBufferImpl::updateData(GrGpuGL* gpu, const void* src, size_t srcSizeInBytes) { |
michael@0 | 108 | SkASSERT(!this->isLocked()); |
michael@0 | 109 | VALIDATE(); |
michael@0 | 110 | if (srcSizeInBytes > fDesc.fSizeInBytes) { |
michael@0 | 111 | return false; |
michael@0 | 112 | } |
michael@0 | 113 | if (0 == fDesc.fID) { |
michael@0 | 114 | memcpy(fCPUData, src, srcSizeInBytes); |
michael@0 | 115 | return true; |
michael@0 | 116 | } |
michael@0 | 117 | this->bind(gpu); |
michael@0 | 118 | GrGLenum usage = fDesc.fDynamic ? DYNAMIC_USAGE_PARAM : GR_GL_STATIC_DRAW; |
michael@0 | 119 | |
michael@0 | 120 | #if GR_GL_USE_BUFFER_DATA_NULL_HINT |
michael@0 | 121 | if (fDesc.fSizeInBytes == srcSizeInBytes) { |
michael@0 | 122 | GL_CALL(gpu, BufferData(fBufferType, (GrGLsizeiptr) srcSizeInBytes, src, usage)); |
michael@0 | 123 | } else { |
michael@0 | 124 | // Before we call glBufferSubData we give the driver a hint using |
michael@0 | 125 | // glBufferData with NULL. This makes the old buffer contents |
michael@0 | 126 | // inaccessible to future draws. The GPU may still be processing |
michael@0 | 127 | // draws that reference the old contents. With this hint it can |
michael@0 | 128 | // assign a different allocation for the new contents to avoid |
michael@0 | 129 | // flushing the gpu past draws consuming the old contents. |
michael@0 | 130 | GL_CALL(gpu, BufferData(fBufferType, (GrGLsizeiptr) fDesc.fSizeInBytes, NULL, usage)); |
michael@0 | 131 | GL_CALL(gpu, BufferSubData(fBufferType, 0, (GrGLsizeiptr) srcSizeInBytes, src)); |
michael@0 | 132 | } |
michael@0 | 133 | #else |
michael@0 | 134 | // Note that we're cheating on the size here. Currently no methods |
michael@0 | 135 | // allow a partial update that preserves contents of non-updated |
michael@0 | 136 | // portions of the buffer (lock() does a glBufferData(..size, NULL..)) |
michael@0 | 137 | bool doSubData = false; |
michael@0 | 138 | #if GR_GL_MAC_BUFFER_OBJECT_PERFOMANCE_WORKAROUND |
michael@0 | 139 | static int N = 0; |
michael@0 | 140 | // 128 was chosen experimentally. At 256 a slight hitchiness was noticed |
michael@0 | 141 | // when dragging a Chromium window around with a canvas tab backgrounded. |
michael@0 | 142 | doSubData = 0 == (N % 128); |
michael@0 | 143 | ++N; |
michael@0 | 144 | #endif |
michael@0 | 145 | if (doSubData) { |
michael@0 | 146 | // The workaround is to do a glBufferData followed by glBufferSubData. |
michael@0 | 147 | // Chromium's command buffer may turn a glBufferSubData where the size |
michael@0 | 148 | // exactly matches the buffer size into a glBufferData. So we tack 1 |
michael@0 | 149 | // extra byte onto the glBufferData. |
michael@0 | 150 | GL_CALL(gpu, BufferData(fBufferType, srcSizeInBytes + 1, NULL, usage)); |
michael@0 | 151 | GL_CALL(gpu, BufferSubData(fBufferType, 0, srcSizeInBytes, src)); |
michael@0 | 152 | } else { |
michael@0 | 153 | GL_CALL(gpu, BufferData(fBufferType, srcSizeInBytes, src, usage)); |
michael@0 | 154 | } |
michael@0 | 155 | #endif |
michael@0 | 156 | return true; |
michael@0 | 157 | } |
michael@0 | 158 | |
michael@0 | 159 | void GrGLBufferImpl::validate() const { |
michael@0 | 160 | SkASSERT(GR_GL_ARRAY_BUFFER == fBufferType || GR_GL_ELEMENT_ARRAY_BUFFER == fBufferType); |
michael@0 | 161 | // The following assert isn't valid when the buffer has been abandoned: |
michael@0 | 162 | // SkASSERT((0 == fDesc.fID) == (NULL != fCPUData)); |
michael@0 | 163 | SkASSERT(0 != fDesc.fID || !fDesc.fIsWrapped); |
michael@0 | 164 | SkASSERT(NULL == fCPUData || NULL == fLockPtr || fCPUData == fLockPtr); |
michael@0 | 165 | } |