mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 1168015 - Dump source image from graphic buffer directly on B2G. r=kamidphish, r=hshih
This commit is contained in:
parent
21de128d37
commit
747011926e
@ -74,6 +74,7 @@ struct TexturedEffect : public Effect
|
||||
TextureSource* mTexture;
|
||||
bool mPremultiplied;
|
||||
gfx::Filter mFilter;
|
||||
LayerRenderState mState;
|
||||
};
|
||||
|
||||
// Support an alpha mask.
|
||||
@ -248,7 +249,8 @@ inline TemporaryRef<TexturedEffect>
|
||||
CreateTexturedEffect(gfx::SurfaceFormat aFormat,
|
||||
TextureSource* aSource,
|
||||
const gfx::Filter& aFilter,
|
||||
bool isAlphaPremultiplied)
|
||||
bool isAlphaPremultiplied,
|
||||
const LayerRenderState &state = LayerRenderState())
|
||||
{
|
||||
MOZ_ASSERT(aSource);
|
||||
RefPtr<TexturedEffect> result;
|
||||
@ -268,6 +270,8 @@ CreateTexturedEffect(gfx::SurfaceFormat aFormat,
|
||||
break;
|
||||
}
|
||||
|
||||
result->mState = state;
|
||||
|
||||
return result.forget();
|
||||
}
|
||||
|
||||
@ -281,7 +285,8 @@ inline TemporaryRef<TexturedEffect>
|
||||
CreateTexturedEffect(TextureSource* aSource,
|
||||
TextureSource* aSourceOnWhite,
|
||||
const gfx::Filter& aFilter,
|
||||
bool isAlphaPremultiplied)
|
||||
bool isAlphaPremultiplied,
|
||||
const LayerRenderState &state = LayerRenderState())
|
||||
{
|
||||
MOZ_ASSERT(aSource);
|
||||
if (aSourceOnWhite) {
|
||||
@ -294,7 +299,8 @@ CreateTexturedEffect(TextureSource* aSource,
|
||||
return CreateTexturedEffect(aSource->GetFormat(),
|
||||
aSource,
|
||||
aFilter,
|
||||
isAlphaPremultiplied);
|
||||
isAlphaPremultiplied,
|
||||
state);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -304,9 +310,10 @@ CreateTexturedEffect(TextureSource* aSource,
|
||||
*/
|
||||
inline TemporaryRef<TexturedEffect>
|
||||
CreateTexturedEffect(TextureSource *aTexture,
|
||||
const gfx::Filter& aFilter)
|
||||
const gfx::Filter& aFilter,
|
||||
const LayerRenderState &state = LayerRenderState())
|
||||
{
|
||||
return CreateTexturedEffect(aTexture, nullptr, aFilter, true);
|
||||
return CreateTexturedEffect(aTexture, nullptr, aFilter, true, state);
|
||||
}
|
||||
|
||||
|
||||
|
@ -270,6 +270,87 @@ protected:
|
||||
int64_t mFrameStamp;
|
||||
};
|
||||
|
||||
#ifdef MOZ_WIDGET_GONK
|
||||
// B2G optimization.
|
||||
class DebugGLGraphicBuffer final: public DebugGLData {
|
||||
public:
|
||||
DebugGLGraphicBuffer(void *layerRef,
|
||||
GLenum target,
|
||||
GLuint name,
|
||||
const LayerRenderState &aState)
|
||||
: DebugGLData(Packet::TEXTURE),
|
||||
mLayerRef(reinterpret_cast<uint64_t>(layerRef)),
|
||||
mTarget(target),
|
||||
mName(name),
|
||||
mState(aState)
|
||||
{
|
||||
}
|
||||
|
||||
virtual bool Write() override {
|
||||
return WriteToStream(mPacket);
|
||||
}
|
||||
|
||||
bool TryPack() {
|
||||
android::sp<android::GraphicBuffer> buffer = mState.mSurface;
|
||||
MOZ_ASSERT(buffer.get());
|
||||
|
||||
mPacket.set_type(mDataType);
|
||||
TexturePacket* tp = mPacket.mutable_texture();
|
||||
tp->set_layerref(mLayerRef);
|
||||
tp->set_name(mName);
|
||||
tp->set_target(mTarget);
|
||||
|
||||
int format = buffer->getPixelFormat();
|
||||
if (HAL_PIXEL_FORMAT_RGBA_8888 != format &&
|
||||
HAL_PIXEL_FORMAT_RGBX_8888 != format) {
|
||||
return false;
|
||||
}
|
||||
|
||||
uint8_t* grallocData;
|
||||
if (BAD_VALUE == buffer->lock(GRALLOC_USAGE_SW_READ_OFTEN |
|
||||
GRALLOC_USAGE_SW_WRITE_NEVER,
|
||||
reinterpret_cast<void**>(&grallocData))) {
|
||||
return false;
|
||||
}
|
||||
|
||||
int32_t stride = buffer->getStride() * 4;
|
||||
int32_t height = buffer->getHeight();
|
||||
int32_t width = buffer->getWidth();
|
||||
int32_t sourceSize = stride * height;
|
||||
bool ret = false;
|
||||
|
||||
if (sourceSize > 0) {
|
||||
auto compressedData = MakeUnique<char[]>(LZ4::maxCompressedSize(sourceSize));
|
||||
int compressedSize = LZ4::compress((char*)grallocData,
|
||||
sourceSize,
|
||||
compressedData.get());
|
||||
|
||||
if (compressedSize > 0) {
|
||||
uint32_t format = mState.FormatRBSwapped() ?
|
||||
LOCAL_GL_BGRA : LOCAL_GL_RGBA;
|
||||
tp->set_dataformat(format);
|
||||
tp->set_dataformat((1 << 16 | tp->dataformat()));
|
||||
tp->set_width(width);
|
||||
tp->set_height(height);
|
||||
tp->set_stride(stride);
|
||||
tp->set_data(compressedData.get(), compressedSize);
|
||||
ret = true;
|
||||
}
|
||||
}
|
||||
|
||||
buffer->unlock();
|
||||
return ret;
|
||||
}
|
||||
|
||||
private:
|
||||
uint64_t mLayerRef;
|
||||
GLenum mTarget;
|
||||
GLuint mName;
|
||||
const LayerRenderState &mState;
|
||||
Packet mPacket;
|
||||
};
|
||||
#endif
|
||||
|
||||
class DebugGLTextureData final: public DebugGLData {
|
||||
public:
|
||||
DebugGLTextureData(GLContext* cx,
|
||||
@ -608,7 +689,6 @@ public:
|
||||
|
||||
static void ClearTextureIdList();
|
||||
|
||||
static bool IsTextureIdContainsInList(GLuint aTextureId);
|
||||
|
||||
// Sender private functions
|
||||
private:
|
||||
@ -619,14 +699,23 @@ private:
|
||||
static void SendTextureSource(GLContext* aGLContext,
|
||||
void* aLayerRef,
|
||||
TextureSourceOGL* aSource,
|
||||
GLuint aTexID,
|
||||
bool aFlipY);
|
||||
#ifdef MOZ_WIDGET_GONK
|
||||
static bool SendGraphicBuffer(void* aLayerRef,
|
||||
TextureSourceOGL* aSource,
|
||||
GLuint aTexID,
|
||||
const TexturedEffect* aEffect);
|
||||
#endif
|
||||
static void SendTexturedEffect(GLContext* aGLContext,
|
||||
void* aLayerRef,
|
||||
const TexturedEffect* aEffect);
|
||||
static void SendYCbCrEffect(GLContext* aGLContext,
|
||||
void* aLayerRef,
|
||||
const EffectYCbCr* aEffect);
|
||||
|
||||
static GLuint GetTextureID(GLContext* aGLContext,
|
||||
TextureSourceOGL* aSource);
|
||||
static bool IsTextureIdContainsInList(GLuint aTextureId);
|
||||
// Data fields
|
||||
private:
|
||||
static bool sLayersTreeSendable;
|
||||
@ -714,10 +803,31 @@ SenderHelper::SendColor(void* aLayerRef,
|
||||
new DebugGLColorData(aLayerRef, aColor, aWidth, aHeight));
|
||||
}
|
||||
|
||||
GLuint
|
||||
SenderHelper::GetTextureID(GLContext* aGLContext,
|
||||
TextureSourceOGL* aSource) {
|
||||
GLenum textureTarget = aSource->GetTextureTarget();
|
||||
aSource->BindTexture(LOCAL_GL_TEXTURE0, gfx::Filter::LINEAR);
|
||||
|
||||
GLuint texID = 0;
|
||||
// This is horrid hack. It assumes that aGLContext matches the context
|
||||
// aSource has bound to.
|
||||
if (textureTarget == LOCAL_GL_TEXTURE_2D) {
|
||||
aGLContext->GetUIntegerv(LOCAL_GL_TEXTURE_BINDING_2D, &texID);
|
||||
} else if (textureTarget == LOCAL_GL_TEXTURE_EXTERNAL) {
|
||||
aGLContext->GetUIntegerv(LOCAL_GL_TEXTURE_BINDING_EXTERNAL, &texID);
|
||||
} else if (textureTarget == LOCAL_GL_TEXTURE_RECTANGLE) {
|
||||
aGLContext->GetUIntegerv(LOCAL_GL_TEXTURE_BINDING_RECTANGLE, &texID);
|
||||
}
|
||||
|
||||
return texID;
|
||||
}
|
||||
|
||||
void
|
||||
SenderHelper::SendTextureSource(GLContext* aGLContext,
|
||||
void* aLayerRef,
|
||||
TextureSourceOGL* aSource,
|
||||
GLuint aTexID,
|
||||
bool aFlipY)
|
||||
{
|
||||
MOZ_ASSERT(aGLContext);
|
||||
@ -730,46 +840,68 @@ SenderHelper::SendTextureSource(GLContext* aGLContext,
|
||||
aSource->GetFormat());
|
||||
int shaderConfig = config.mFeatures;
|
||||
|
||||
aSource->BindTexture(LOCAL_GL_TEXTURE0, gfx::Filter::LINEAR);
|
||||
|
||||
GLuint textureId = 0;
|
||||
// This is horrid hack. It assumes that aGLContext matches the context
|
||||
// aSource has bound to.
|
||||
if (textureTarget == LOCAL_GL_TEXTURE_2D) {
|
||||
aGLContext->GetUIntegerv(LOCAL_GL_TEXTURE_BINDING_2D, &textureId);
|
||||
} else if (textureTarget == LOCAL_GL_TEXTURE_EXTERNAL) {
|
||||
aGLContext->GetUIntegerv(LOCAL_GL_TEXTURE_BINDING_EXTERNAL, &textureId);
|
||||
} else if (textureTarget == LOCAL_GL_TEXTURE_RECTANGLE) {
|
||||
aGLContext->GetUIntegerv(LOCAL_GL_TEXTURE_BINDING_RECTANGLE, &textureId);
|
||||
}
|
||||
|
||||
if (!IsTextureIdContainsInList(textureId)) {
|
||||
gfx::IntSize size = aSource->GetSize();
|
||||
|
||||
// By sending 0 to ReadTextureImage rely upon aSource->BindTexture binding
|
||||
// texture correctly. textureId is used for tracking in DebugGLTextureData.
|
||||
// texture correctly. texID is used for tracking in DebugGLTextureData.
|
||||
RefPtr<DataSourceSurface> img =
|
||||
aGLContext->ReadTexImageHelper()->ReadTexImage(0, textureTarget,
|
||||
size,
|
||||
shaderConfig, aFlipY);
|
||||
sTextureIdList.push_back(textureId);
|
||||
WebSocketHelper::GetSocketManager()->AppendDebugData(
|
||||
new DebugGLTextureData(aGLContext, aLayerRef, textureTarget,
|
||||
textureId, img));
|
||||
aTexID, img));
|
||||
|
||||
sTextureIdList.push_back(aTexID);
|
||||
}
|
||||
|
||||
#ifdef MOZ_WIDGET_GONK
|
||||
bool
|
||||
SenderHelper::SendGraphicBuffer(void* aLayerRef,
|
||||
TextureSourceOGL* aSource,
|
||||
GLuint aTexID,
|
||||
const TexturedEffect* aEffect) {
|
||||
if (!aEffect->mState.mSurface.get()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
GLenum target = aSource->GetTextureTarget();
|
||||
mozilla::UniquePtr<DebugGLGraphicBuffer> package =
|
||||
MakeUnique<DebugGLGraphicBuffer>(aLayerRef, target, aTexID, aEffect->mState);
|
||||
|
||||
if (!package->TryPack()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Transfer ownership to SocketManager.
|
||||
WebSocketHelper::GetSocketManager()->AppendDebugData(package.release());
|
||||
sTextureIdList.push_back(aTexID);
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
|
||||
void
|
||||
SenderHelper::SendTexturedEffect(GLContext* aGLContext,
|
||||
void* aLayerRef,
|
||||
const TexturedEffect* aEffect)
|
||||
{
|
||||
TextureSourceOGL* source = aEffect->mTexture->AsSourceOGL();
|
||||
if (!source)
|
||||
if (!source) {
|
||||
return;
|
||||
}
|
||||
|
||||
bool flipY = false;
|
||||
SendTextureSource(aGLContext, aLayerRef, source, flipY);
|
||||
GLuint texID = GetTextureID(aGLContext, source);
|
||||
if (IsTextureIdContainsInList(texID)) {
|
||||
return;
|
||||
}
|
||||
|
||||
#ifdef MOZ_WIDGET_GONK
|
||||
if (SendGraphicBuffer(aLayerRef, source, texID, aEffect)) {
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
// Render to texture and read pixels back.
|
||||
SendTextureSource(aGLContext, aLayerRef, source, texID, false);
|
||||
}
|
||||
|
||||
void
|
||||
@ -786,10 +918,20 @@ SenderHelper::SendYCbCrEffect(GLContext* aGLContext,
|
||||
TextureSourceOGL* sourceCb = sourceYCbCr->GetSubSource(Cb)->AsSourceOGL();
|
||||
TextureSourceOGL* sourceCr = sourceYCbCr->GetSubSource(Cr)->AsSourceOGL();
|
||||
|
||||
bool flipY = false;
|
||||
SendTextureSource(aGLContext, aLayerRef, sourceY, flipY);
|
||||
SendTextureSource(aGLContext, aLayerRef, sourceCb, flipY);
|
||||
SendTextureSource(aGLContext, aLayerRef, sourceCr, flipY);
|
||||
GLuint texID = GetTextureID(aGLContext, sourceY);
|
||||
if (!IsTextureIdContainsInList(texID)) {
|
||||
SendTextureSource(aGLContext, aLayerRef, sourceY, texID, false);
|
||||
}
|
||||
|
||||
texID = GetTextureID(aGLContext, sourceCb);
|
||||
if (!IsTextureIdContainsInList(texID)) {
|
||||
SendTextureSource(aGLContext, aLayerRef, sourceCb, texID, false);
|
||||
}
|
||||
|
||||
texID = GetTextureID(aGLContext, sourceCr);
|
||||
if (!IsTextureIdContainsInList(texID)) {
|
||||
SendTextureSource(aGLContext, aLayerRef, sourceCr, texID, false);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -63,7 +63,8 @@ ContentHostTexture::Composite(EffectChain& aEffectChain,
|
||||
|
||||
RefPtr<TexturedEffect> effect = CreateTexturedEffect(mTextureSource.get(),
|
||||
mTextureSourceOnWhite.get(),
|
||||
aFilter, true);
|
||||
aFilter, true,
|
||||
GetRenderState());
|
||||
if (!effect) {
|
||||
return;
|
||||
}
|
||||
@ -460,7 +461,8 @@ ContentHostTexture::GenEffect(const gfx::Filter& aFilter)
|
||||
}
|
||||
return CreateTexturedEffect(mTextureSource.get(),
|
||||
mTextureSourceOnWhite.get(),
|
||||
aFilter, true);
|
||||
aFilter, true,
|
||||
GetRenderState());
|
||||
}
|
||||
|
||||
TemporaryRef<gfx::DataSourceSurface>
|
||||
|
@ -106,7 +106,8 @@ ImageHost::Composite(EffectChain& aEffectChain,
|
||||
RefPtr<TexturedEffect> effect = CreateTexturedEffect(mFrontBuffer->GetFormat(),
|
||||
mTextureSource.get(),
|
||||
aFilter,
|
||||
isAlphaPremultiplied);
|
||||
isAlphaPremultiplied,
|
||||
GetRenderState());
|
||||
if (!effect) {
|
||||
return;
|
||||
}
|
||||
@ -298,7 +299,8 @@ ImageHost::GenEffect(const gfx::Filter& aFilter)
|
||||
return CreateTexturedEffect(mFrontBuffer->GetFormat(),
|
||||
mTextureSource,
|
||||
aFilter,
|
||||
isAlphaPremultiplied);
|
||||
isAlphaPremultiplied,
|
||||
GetRenderState());
|
||||
}
|
||||
|
||||
#ifdef MOZ_WIDGET_GONK
|
||||
|
@ -468,7 +468,12 @@ TiledContentHost::RenderTile(TileHost& aTile,
|
||||
return;
|
||||
}
|
||||
|
||||
RefPtr<TexturedEffect> effect = CreateTexturedEffect(aTile.mTextureSource, aTile.mTextureSourceOnWhite, aFilter, true);
|
||||
RefPtr<TexturedEffect> effect =
|
||||
CreateTexturedEffect(aTile.mTextureSource,
|
||||
aTile.mTextureSourceOnWhite,
|
||||
aFilter,
|
||||
true,
|
||||
aTile.mTextureHost->GetRenderState());
|
||||
if (!effect) {
|
||||
return;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user