Backed out changeset 6150269410b2 (bug 921212) for bustage on a CLOSED TREE.

This commit is contained in:
Ryan VanderMeulen
2013-10-18 10:21:38 -04:00
parent aaa0464824
commit 92b01d4f75
11 changed files with 18 additions and 323 deletions

View File

@@ -578,15 +578,6 @@ public:
virtual TemporaryRef<SourceSurface> Snapshot() = 0; virtual TemporaryRef<SourceSurface> Snapshot() = 0;
virtual IntSize GetSize() = 0; virtual IntSize GetSize() = 0;
/**
* If possible returns the bits to this DrawTarget for direct manipulation. While
* the bits is locked any modifications to this DrawTarget is forbidden.
* Release takes the original data pointer for safety.
*/
virtual bool LockBits(uint8_t** aData, IntSize* aSize,
int32_t* aStride, SurfaceFormat* aFormat) { return false; }
virtual void ReleaseBits(uint8_t* aData) {}
/* Ensure that the DrawTarget backend has flushed all drawing operations to /* Ensure that the DrawTarget backend has flushed all drawing operations to
* this draw target. This must be called before using the backing surface of * this draw target. This must be called before using the backing surface of
* this draw target outside of GFX 2D code. * this draw target outside of GFX 2D code.

View File

@@ -399,7 +399,6 @@ NeedIntermediateSurface(const Pattern& aPattern, const DrawOptions& aOptions)
DrawTargetCairo::DrawTargetCairo() DrawTargetCairo::DrawTargetCairo()
: mContext(nullptr) : mContext(nullptr)
, mLockedBits(nullptr)
{ {
} }
@@ -409,7 +408,6 @@ DrawTargetCairo::~DrawTargetCairo()
if (mSurface) { if (mSurface) {
cairo_surface_destroy(mSurface); cairo_surface_destroy(mSurface);
} }
MOZ_ASSERT(!mLockedBits);
} }
IntSize IntSize
@@ -435,31 +433,6 @@ DrawTargetCairo::Snapshot()
return mSnapshot; return mSnapshot;
} }
bool
DrawTargetCairo::LockBits(uint8_t** aData, IntSize* aSize,
int32_t* aStride, SurfaceFormat* aFormat)
{
if (cairo_surface_get_type(mSurface) == CAIRO_SURFACE_TYPE_IMAGE) {
WillChange();
mLockedBits = cairo_image_surface_get_data(mSurface);
*aData = mLockedBits;
*aSize = GetSize();
*aStride = cairo_image_surface_get_stride(mSurface);
*aFormat = GetFormat();
return true;
}
return false;
}
void
DrawTargetCairo::ReleaseBits(uint8_t* aData)
{
MOZ_ASSERT(mLockedBits = aData);
mLockedBits = nullptr;
}
void void
DrawTargetCairo::Flush() DrawTargetCairo::Flush()
{ {
@@ -1166,7 +1139,6 @@ void
DrawTargetCairo::WillChange(const Path* aPath /* = nullptr */) DrawTargetCairo::WillChange(const Path* aPath /* = nullptr */)
{ {
MarkSnapshotIndependent(); MarkSnapshotIndependent();
MOZ_ASSERT(!mLiveSurface);
} }
void void

View File

@@ -60,10 +60,6 @@ public:
virtual TemporaryRef<SourceSurface> Snapshot(); virtual TemporaryRef<SourceSurface> Snapshot();
virtual IntSize GetSize(); virtual IntSize GetSize();
virtual bool LockBits(uint8_t** aData, IntSize* aSize,
int32_t* aStride, SurfaceFormat* aFormat);
virtual void ReleaseBits(uint8_t* aData);
virtual void Flush(); virtual void Flush();
virtual void DrawSurface(SourceSurface *aSurface, virtual void DrawSurface(SourceSurface *aSurface,
const Rect &aDest, const Rect &aDest,
@@ -188,8 +184,6 @@ private: // data
cairo_surface_t* mSurface; cairo_surface_t* mSurface;
IntSize mSize; IntSize mSize;
uint8_t* mLockedBits;
// The latest snapshot of this surface. This needs to be told when this // The latest snapshot of this surface. This needs to be told when this
// target is modified. We keep it alive as a cache. // target is modified. We keep it alive as a cache.
RefPtr<SourceSurfaceCairo> mSnapshot; RefPtr<SourceSurfaceCairo> mSnapshot;

View File

@@ -1,63 +0,0 @@
/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*-
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include <algorithm> // min & max
#include <cstdlib>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
void BufferUnrotate(uint8_t* aBuffer, int aByteWidth, int aHeight,
int aByteStride, int aXBoundary, int aYBoundary)
{
if (aXBoundary != 0) {
uint8_t* line = new uint8_t[aByteWidth];
uint32_t smallStart = 0;
uint32_t smallLen = aXBoundary;
uint32_t smallDest = aByteWidth - aXBoundary;
uint32_t largeStart = aXBoundary;
uint32_t largeLen = aByteWidth - aXBoundary;
uint32_t largeDest = 0;
if (aXBoundary > aByteWidth / 2) {
smallStart = aXBoundary;
smallLen = aByteWidth - aXBoundary;
smallDest = 0;
largeStart = 0;
largeLen = aXBoundary;
largeDest = smallLen;
}
for (int y = 0; y < aHeight; y++) {
int yOffset = y * aByteStride;
memcpy(line, &aBuffer[yOffset + smallStart], smallLen);
memmove(&aBuffer[yOffset + largeDest], &aBuffer[yOffset + largeStart], largeLen);
memcpy(&aBuffer[yOffset + smallDest], line, smallLen);
}
delete[] line;
}
if (aYBoundary != 0) {
uint32_t smallestHeight = std::min(aHeight - aYBoundary, aYBoundary);
uint32_t largestHeight = std::max(aHeight - aYBoundary, aYBoundary);
uint32_t smallOffset = 0;
uint32_t largeOffset = aYBoundary * aByteStride;
uint32_t largeDestOffset = 0;
uint32_t smallDestOffset = largestHeight * aByteStride;
if (aYBoundary > aHeight / 2) {
smallOffset = aYBoundary * aByteStride;
largeOffset = 0;
largeDestOffset = smallestHeight * aByteStride;
smallDestOffset = 0;
}
uint8_t* smallestSide = new uint8_t[aByteStride * smallestHeight];
memcpy(smallestSide, &aBuffer[smallOffset], aByteStride * smallestHeight);
memmove(&aBuffer[largeDestOffset], &aBuffer[largeOffset], aByteStride * largestHeight);
memcpy(&aBuffer[smallDestOffset], smallestSide, aByteStride * smallestHeight);
delete[] smallestSide;
}
}

View File

@@ -1,14 +0,0 @@
/* -*- Mode: C++; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 2 -*-
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef GFX_BUFFERUNROTATE_H
#define GFX_BUFFERUNROTATE_H
#include "mozilla/Types.h"
void BufferUnrotate(uint8_t* aBuffer, int aByteWidth, int aHeight,
int aByteStride, int aXByteBoundary, int aYBoundary);
#endif // GFX_BUFFERUNROTATE_H

View File

@@ -8,7 +8,6 @@
#include <algorithm> // for max #include <algorithm> // for max
#include "BasicImplData.h" // for BasicImplData #include "BasicImplData.h" // for BasicImplData
#include "BasicLayersImpl.h" // for ToData #include "BasicLayersImpl.h" // for ToData
#include "BufferUnrotate.h" // for BufferUnrotate
#include "GeckoProfiler.h" // for PROFILER_LABEL #include "GeckoProfiler.h" // for PROFILER_LABEL
#include "Layers.h" // for ThebesLayer, Layer, etc #include "Layers.h" // for ThebesLayer, Layer, etc
#include "gfxColor.h" // for gfxRGBA #include "gfxColor.h" // for gfxRGBA
@@ -676,54 +675,18 @@ ThebesLayerBuffer::BeginPaint(ThebesLayer* aLayer, ContentType aContentType,
} }
} }
result.mDidSelfCopy = true; result.mDidSelfCopy = true;
mDidSelfCopy = true;
// Don't set destBuffer; we special-case self-copies, and // Don't set destBuffer; we special-case self-copies, and
// just did the necessary work above. // just did the necessary work above.
mBufferRect = destBufferRect; mBufferRect = destBufferRect;
} else { } else {
// With azure and a data surface perform an buffer unrotate // We can't do a real self-copy because the buffer is rotated.
// (SelfCopy). // So allocate a new buffer for the destination.
if (IsAzureBuffer()) { destBufferRect = ComputeBufferRect(neededRegion.GetBounds());
unsigned char* data; CreateBuffer(contentType, destBufferRect, bufferFlags,
IntSize size; getter_AddRefs(destBuffer), getter_AddRefs(destBufferOnWhite),
int32_t stride; &destDTBuffer, &destDTBufferOnWhite);
SurfaceFormat format; if (!destBuffer && !destDTBuffer)
return result;
if (mDTBuffer->LockBits(&data, &size, &stride, &format)) {
uint8_t bytesPerPixel = BytesPerPixel(format);
BufferUnrotate(data,
size.width * bytesPerPixel,
size.height, stride,
newRotation.x * bytesPerPixel, newRotation.y);
mDTBuffer->ReleaseBits(data);
if (mode == Layer::SURFACE_COMPONENT_ALPHA) {
mDTBufferOnWhite->LockBits(&data, &size, &stride, &format);
uint8_t bytesPerPixel = BytesPerPixel(format);
BufferUnrotate(data,
size.width * bytesPerPixel,
size.height, stride,
newRotation.x * bytesPerPixel, newRotation.y);
mDTBufferOnWhite->ReleaseBits(data);
}
// Buffer unrotate moves all the pixels, note that
// we self copied for SyncBackToFrontBuffer
result.mDidSelfCopy = true;
mDidSelfCopy = true;
mBufferRect = destBufferRect;
mBufferRotation = nsIntPoint(0, 0);
}
}
if (!result.mDidSelfCopy) {
destBufferRect = ComputeBufferRect(neededRegion.GetBounds());
CreateBuffer(contentType, destBufferRect, bufferFlags,
getter_AddRefs(destBuffer), getter_AddRefs(destBufferOnWhite),
&destDTBuffer, &destDTBufferOnWhite);
if (!destBuffer && !destDTBuffer)
return result;
}
} }
} else { } else {
mBufferRect = destBufferRect; mBufferRect = destBufferRect;

View File

@@ -146,9 +146,6 @@ protected:
* buffer at the other end, not 2D rotation! * buffer at the other end, not 2D rotation!
*/ */
nsIntPoint mBufferRotation; nsIntPoint mBufferRotation;
// When this is true it means that all pixels have moved inside the buffer.
// It's not possible to sync with another buffer without a full copy.
bool mDidSelfCopy;
}; };
/** /**

View File

@@ -479,13 +479,21 @@ ContentClientDoubleBuffered::SyncFrontBufferToBackBuffer()
nsIntRegion updateRegion = mFrontUpdatedRegion; nsIntRegion updateRegion = mFrontUpdatedRegion;
int32_t xBoundary = mBufferRect.XMost() - mBufferRotation.x;
int32_t yBoundary = mBufferRect.YMost() - mBufferRotation.y;
// Figure out whether the area we want to copy wraps the edges of our buffer.
bool needFullCopy = (xBoundary < updateRegion.GetBounds().XMost() &&
xBoundary > updateRegion.GetBounds().x) ||
(yBoundary < updateRegion.GetBounds().YMost() &&
yBoundary > updateRegion.GetBounds().y);
// This is a tricky trade off, we're going to get stuff out of our // This is a tricky trade off, we're going to get stuff out of our
// frontbuffer now, but the next PaintThebes might throw it all (or mostly) // frontbuffer now, but the next PaintThebes might throw it all (or mostly)
// away if the visible region has changed. This is why in reality we want // away if the visible region has changed. This is why in reality we want
// this code integrated with PaintThebes to always do the optimal thing. // this code integrated with PaintThebes to always do the optimal thing.
if (mDidSelfCopy) { if (needFullCopy) {
mDidSelfCopy = false;
// We can't easily draw our front buffer into us, since we're going to be // We can't easily draw our front buffer into us, since we're going to be
// copying stuff around anyway it's easiest if we just move our situation // copying stuff around anyway it's easiest if we just move our situation
// to non-rotated while we're at it. If this situation occurs we'll have // to non-rotated while we're at it. If this situation occurs we'll have

View File

@@ -194,7 +194,6 @@ CPP_SOURCES += [
'basic/BasicLayerManager.cpp', 'basic/BasicLayerManager.cpp',
'basic/BasicLayersImpl.cpp', 'basic/BasicLayersImpl.cpp',
'basic/BasicThebesLayer.cpp', 'basic/BasicThebesLayer.cpp',
'BufferUnrotate.cpp',
'client/CanvasClient.cpp', 'client/CanvasClient.cpp',
'composite/CanvasLayerComposite.cpp', 'composite/CanvasLayerComposite.cpp',
'opengl/CanvasLayerOGL.cpp', 'opengl/CanvasLayerOGL.cpp',

View File

@@ -1,151 +0,0 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "gtest/gtest.h"
#include "BufferUnrotate.h"
static unsigned char* GenerateBuffer(int bytesPerPixel,
int width, int height,
int stride, int xBoundary, int yBoundary)
{
unsigned char* buffer = new unsigned char[stride*height];
for (int y = 0; y < height; y++) {
for (int x = 0; x < width; x++) {
int pos = ((yBoundary + y) % height) * stride +
((xBoundary + x) % width) * bytesPerPixel;
for (int i = 0; i < bytesPerPixel; i++) {
buffer[pos+i] = (x+y+i*2)%256;
}
}
}
return buffer;
}
static bool CheckBuffer(unsigned char* buffer, int bytesPerPixel,
int width, int height, int stride)
{
int xBoundary = 0;
int yBoundary = 0;
for (int y = 0; y < height; y++) {
for (int x = 0; x < width; x++) {
int pos = ((yBoundary + y) % height) * stride +
((xBoundary + x) % width) * bytesPerPixel;
for (int i = 0; i < bytesPerPixel; i++) {
if (buffer[pos+i] != (x+y+i*2)%256) {
printf("Buffer differs at %i, %i, is %i\n", x, y, (int)buffer[pos+i]);
return false;
}
}
}
}
return true;
}
TEST(Gfx, BufferUnrotateHorizontal) {
const int NUM_OF_TESTS = 8;
int bytesPerPixelList[2] = {2,4};
int width[NUM_OF_TESTS] = {100, 100, 99, 99, 100, 100, 99, 99};
int height[NUM_OF_TESTS] = {100, 99, 100, 99, 100, 99, 100, 99};
int xBoundary[NUM_OF_TESTS] = {30, 30, 30, 30, 31, 31, 31, 31};
int yBoundary[NUM_OF_TESTS] = {0, 0, 0, 0};
for (int bytesPerId = 0; bytesPerId < 2; bytesPerId++) {
int bytesPerPixel = bytesPerPixelList[bytesPerId];
int stride = 256 * bytesPerPixel;
for (int testId = 0; testId < NUM_OF_TESTS; testId++) {
unsigned char* buffer = GenerateBuffer(bytesPerPixel,
width[testId], height[testId], stride,
xBoundary[testId], yBoundary[testId]);
BufferUnrotate(buffer,
width[testId] * bytesPerPixel, height[testId], stride,
xBoundary[testId] * bytesPerPixel, yBoundary[testId]);
EXPECT_TRUE(CheckBuffer(buffer, bytesPerPixel,
width[testId], height[testId], stride));
delete[] buffer;
}
}
}
TEST(Gfx, BufferUnrotateVertical) {
const int NUM_OF_TESTS = 8;
int bytesPerPixelList[2] = {2,4};
int width[NUM_OF_TESTS] = {100, 100, 99, 99, 100, 100, 99, 99};
int height[NUM_OF_TESTS] = {100, 99, 100, 99, 100, 99, 100, 99};
int xBoundary[NUM_OF_TESTS] = {0, 0, 0, 0};
int yBoundary[NUM_OF_TESTS] = {30, 30, 30, 30, 31, 31, 31, 31};
for (int bytesPerId = 0; bytesPerId < 2; bytesPerId++) {
int bytesPerPixel = bytesPerPixelList[bytesPerId];
int stride = 256 * bytesPerPixel;
for (int testId = 0; testId < NUM_OF_TESTS; testId++) {
unsigned char* buffer = GenerateBuffer(bytesPerPixel,
width[testId], height[testId], stride,
xBoundary[testId], yBoundary[testId]);
BufferUnrotate(buffer, width[testId] * bytesPerPixel,
height[testId], stride,
xBoundary[testId] * bytesPerPixel, yBoundary[testId]);
EXPECT_TRUE(CheckBuffer(buffer, bytesPerPixel,
width[testId], height[testId], stride));
delete[] buffer;
}
}
}
TEST(Gfx, BufferUnrotateBoth) {
const int NUM_OF_TESTS = 16;
int bytesPerPixelList[2] = {2,4};
int width[NUM_OF_TESTS] = {100, 100, 99, 99, 100, 100, 99, 99, 100, 100, 99, 99, 100, 100, 99, 99};
int height[NUM_OF_TESTS] = {100, 99, 100, 99, 100, 99, 100, 99, 100, 99, 100, 99, 100, 99, 100, 99};
int xBoundary[NUM_OF_TESTS] = {30, 30, 30, 30, 31, 31, 31, 31, 30, 30, 30, 30, 31, 31, 31, 31};
int yBoundary[NUM_OF_TESTS] = {30, 30, 30, 30, 30, 30, 30, 30, 31, 31, 31, 31, 31, 31, 31, 31};
for (int bytesPerId = 0; bytesPerId < 2; bytesPerId++) {
int bytesPerPixel = bytesPerPixelList[bytesPerId];
int stride = 256 * bytesPerPixel;
for (int testId = 0; testId < NUM_OF_TESTS; testId++) {
unsigned char* buffer = GenerateBuffer(bytesPerPixel,
width[testId], height[testId], stride,
xBoundary[testId], yBoundary[testId]);
BufferUnrotate(buffer,
width[testId] * bytesPerPixel, height[testId], stride,
xBoundary[testId] * bytesPerPixel, yBoundary[testId]);
EXPECT_TRUE(CheckBuffer(buffer, bytesPerPixel,
width[testId], height[testId], stride));
delete[] buffer;
}
}
}
TEST(Gfx, BufferUnrotateUneven) {
const int NUM_OF_TESTS = 16;
int bytesPerPixelList[2] = {2,4};
int width[NUM_OF_TESTS] = {10, 100, 99, 39, 100, 40, 99, 39, 100, 50, 39, 99, 74, 60, 99, 39};
int height[NUM_OF_TESTS] = {100, 39, 10, 99, 10, 99, 40, 99, 73, 39, 100, 39, 67, 99, 84, 99};
int xBoundary[NUM_OF_TESTS] = {0, 0, 30, 30, 99, 31, 0, 31, 30, 30, 30, 30, 31, 31, 31, 38};
int yBoundary[NUM_OF_TESTS] = {30, 30, 0, 30, 0, 30, 0, 30, 31, 31, 31, 31, 31, 31, 31, 98};
for (int bytesPerId = 0; bytesPerId < 2; bytesPerId++) {
int bytesPerPixel = bytesPerPixelList[bytesPerId];
int stride = 256 * bytesPerPixel;
for (int testId = 0; testId < NUM_OF_TESTS; testId++) {
unsigned char* buffer = GenerateBuffer(bytesPerPixel,
width[testId], height[testId], stride,
xBoundary[testId], yBoundary[testId]);
BufferUnrotate(buffer,
width[testId]*bytesPerPixel, height[testId], stride,
xBoundary[testId]*bytesPerPixel, yBoundary[testId]);
EXPECT_TRUE(CheckBuffer(buffer, bytesPerPixel, width[testId], height[testId], stride));
delete[] buffer;
}
}
}

View File

@@ -21,7 +21,6 @@ GTEST_CPP_SOURCES += [
'TestRegion.cpp', 'TestRegion.cpp',
'TestColorNames.cpp', 'TestColorNames.cpp',
'TestTextures.cpp', 'TestTextures.cpp',
'TestBufferRotation.cpp',
] ]
# Because of gkmedia on windows we wont find these # Because of gkmedia on windows we wont find these