зеркало из https://github.com/mozilla/gecko-dev.git
Backed out 4 changesets (bug 1652894) for texture related crashes. CLOSED TREE
Backed out changeset 714ad1b01cb2 (bug 1652894) Backed out changeset e3b4753fd09c (bug 1652894) Backed out changeset 8abaf47071d8 (bug 1652894) Backed out changeset 175df7659c3f (bug 1652894)
This commit is contained in:
Родитель
56b4ff381b
Коммит
cc057fb442
|
@ -21,7 +21,6 @@
|
|||
# include "mozilla/layers/D3D11YCbCrImage.h"
|
||||
#elif XP_MACOSX
|
||||
# include "MacIOSurfaceImage.h"
|
||||
# include "mozilla/gfx/gfxVars.h"
|
||||
#endif
|
||||
|
||||
namespace mozilla {
|
||||
|
@ -352,10 +351,8 @@ already_AddRefed<VideoData> VideoData::CreateAndCopyData(
|
|||
}
|
||||
}
|
||||
#elif XP_MACOSX
|
||||
if (aAllocator &&
|
||||
aAllocator->GetCompositorBackendType() ==
|
||||
layers::LayersBackend::LAYERS_WR &&
|
||||
!gfxVars::UseSoftwareWebRender()) {
|
||||
if (aAllocator && aAllocator->GetCompositorBackendType() ==
|
||||
layers::LayersBackend::LAYERS_WR) {
|
||||
RefPtr<layers::MacIOSurfaceImage> ioImage =
|
||||
new layers::MacIOSurfaceImage(nullptr);
|
||||
PlanarYCbCrData data = ConstructPlanarYCbCrData(aInfo, aBuffer, aPicture);
|
||||
|
|
|
@ -32,7 +32,6 @@
|
|||
#include "mozilla/StaticPrefs_layers.h"
|
||||
#include "mozilla/StaticPrefs_gfx.h"
|
||||
#include "mozilla/webrender/RenderBufferTextureHost.h"
|
||||
#include "mozilla/webrender/RenderBufferTextureHostSWGL.h"
|
||||
#include "mozilla/webrender/RenderExternalTextureHost.h"
|
||||
#include "mozilla/webrender/RenderThread.h"
|
||||
#include "mozilla/webrender/WebRenderAPI.h"
|
||||
|
@ -677,9 +676,6 @@ void BufferTextureHost::CreateRenderTexture(
|
|||
if (UseExternalTextures()) {
|
||||
texture =
|
||||
new wr::RenderExternalTextureHost(GetBuffer(), GetBufferDescriptor());
|
||||
} else if (gfx::gfxVars::UseSoftwareWebRender()) {
|
||||
texture =
|
||||
new wr::RenderBufferTextureHostSWGL(GetBuffer(), GetBufferDescriptor());
|
||||
} else {
|
||||
texture =
|
||||
new wr::RenderBufferTextureHost(GetBuffer(), GetBufferDescriptor());
|
||||
|
@ -705,7 +701,7 @@ void BufferTextureHost::PushResourceUpdates(
|
|||
: &wr::TransactionBuilder::UpdateExternalImage;
|
||||
|
||||
auto imageType =
|
||||
UseExternalTextures() || gfx::gfxVars::UseSoftwareWebRender()
|
||||
UseExternalTextures()
|
||||
? wr::ExternalImageType::TextureHandle(wr::TextureTarget::Rect)
|
||||
: wr::ExternalImageType::Buffer();
|
||||
|
||||
|
|
|
@ -11,7 +11,6 @@
|
|||
#include "mozilla/layers/SourceSurfaceSharedData.h"
|
||||
#include "mozilla/layers/CompositorThread.h"
|
||||
#include "mozilla/webrender/RenderSharedSurfaceTextureHost.h"
|
||||
#include "mozilla/webrender/RenderSharedSurfaceTextureHostSWGL.h"
|
||||
#include "mozilla/webrender/RenderThread.h"
|
||||
|
||||
namespace mozilla {
|
||||
|
@ -130,12 +129,8 @@ void SharedSurfacesParent::AddSameProcess(const wr::ExternalImageId& aId,
|
|||
uint64_t id = wr::AsUint64(aId);
|
||||
MOZ_ASSERT(!sInstance->mSurfaces.Contains(id));
|
||||
|
||||
RefPtr<wr::RenderTextureHost> texture;
|
||||
if (gfx::gfxVars::UseSoftwareWebRender()) {
|
||||
texture = new wr::RenderSharedSurfaceTextureHostSWGL(surface);
|
||||
} else {
|
||||
texture = new wr::RenderSharedSurfaceTextureHost(surface);
|
||||
}
|
||||
RefPtr<wr::RenderSharedSurfaceTextureHost> texture =
|
||||
new wr::RenderSharedSurfaceTextureHost(surface);
|
||||
wr::RenderThread::Get()->RegisterExternalImage(id, texture.forget());
|
||||
|
||||
surface->AddConsumer();
|
||||
|
@ -192,12 +187,8 @@ void SharedSurfacesParent::Add(const wr::ExternalImageId& aId,
|
|||
uint64_t id = wr::AsUint64(aId);
|
||||
MOZ_ASSERT(!sInstance->mSurfaces.Contains(id));
|
||||
|
||||
RefPtr<wr::RenderTextureHost> texture;
|
||||
if (gfx::gfxVars::UseSoftwareWebRender()) {
|
||||
texture = new wr::RenderSharedSurfaceTextureHostSWGL(surface);
|
||||
} else {
|
||||
texture = new wr::RenderSharedSurfaceTextureHost(surface);
|
||||
}
|
||||
RefPtr<wr::RenderSharedSurfaceTextureHost> texture =
|
||||
new wr::RenderSharedSurfaceTextureHost(surface);
|
||||
wr::RenderThread::Get()->RegisterExternalImage(id, texture.forget());
|
||||
|
||||
surface->AddConsumer();
|
||||
|
|
|
@ -5,10 +5,8 @@
|
|||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "MacIOSurfaceTextureHostOGL.h"
|
||||
#include "mozilla/gfx/gfxVars.h"
|
||||
#include "mozilla/gfx/MacIOSurface.h"
|
||||
#include "mozilla/webrender/RenderMacIOSurfaceTextureHostOGL.h"
|
||||
#include "mozilla/webrender/RenderMacIOSurfaceTextureHostSWGL.h"
|
||||
#include "mozilla/webrender/RenderThread.h"
|
||||
#include "mozilla/webrender/WebRenderAPI.h"
|
||||
#include "GLContextCGL.h"
|
||||
|
@ -134,12 +132,8 @@ gfx::ColorRange MacIOSurfaceTextureHostOGL::GetColorRange() const {
|
|||
|
||||
void MacIOSurfaceTextureHostOGL::CreateRenderTexture(
|
||||
const wr::ExternalImageId& aExternalImageId) {
|
||||
RefPtr<wr::RenderTextureHost> texture;
|
||||
if (gfx::gfxVars::UseSoftwareWebRender()) {
|
||||
texture = new wr::RenderMacIOSurfaceTextureHostSWGL(GetMacIOSurface());
|
||||
} else {
|
||||
texture = new wr::RenderMacIOSurfaceTextureHostOGL(GetMacIOSurface());
|
||||
}
|
||||
RefPtr<wr::RenderTextureHost> texture =
|
||||
new wr::RenderMacIOSurfaceTextureHostOGL(GetMacIOSurface());
|
||||
|
||||
wr::RenderThread::Get()->RegisterExternalImage(wr::AsUint64(aExternalImageId),
|
||||
texture.forget());
|
||||
|
|
|
@ -693,13 +693,10 @@ bool WebRenderBridgeParent::AddSharedExternalImage(
|
|||
|
||||
mSharedSurfaceIds.insert(std::make_pair(key, aExtId));
|
||||
|
||||
auto imageType =
|
||||
gfx::gfxVars::UseSoftwareWebRender()
|
||||
? wr::ExternalImageType::TextureHandle(wr::TextureTarget::Rect)
|
||||
: wr::ExternalImageType::Buffer();
|
||||
wr::ImageDescriptor descriptor(dSurf->GetSize(), dSurf->Stride(),
|
||||
dSurf->GetFormat());
|
||||
aResources.AddExternalImage(aKey, descriptor, aExtId, imageType, 0);
|
||||
aResources.AddExternalImage(aKey, descriptor, aExtId,
|
||||
wr::ExternalImageType::Buffer(), 0);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -807,14 +804,11 @@ bool WebRenderBridgeParent::UpdateSharedExternalImage(
|
|||
it->second = aExtId;
|
||||
}
|
||||
|
||||
auto imageType =
|
||||
gfx::gfxVars::UseSoftwareWebRender()
|
||||
? wr::ExternalImageType::TextureHandle(wr::TextureTarget::Rect)
|
||||
: wr::ExternalImageType::Buffer();
|
||||
wr::ImageDescriptor descriptor(dSurf->GetSize(), dSurf->Stride(),
|
||||
dSurf->GetFormat());
|
||||
aResources.UpdateExternalImageWithDirtyRect(
|
||||
aKey, descriptor, aExtId, imageType, wr::ToDeviceIntRect(aDirtyRect), 0);
|
||||
aKey, descriptor, aExtId, wr::ExternalImageType::Buffer(),
|
||||
wr::ToDeviceIntRect(aDirtyRect), 0);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -1,88 +0,0 @@
|
|||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
|
||||
/* 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 "RenderBufferTextureHostSWGL.h"
|
||||
|
||||
#include "mozilla/gfx/Logging.h"
|
||||
#include "mozilla/layers/ImageDataSerializer.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace wr {
|
||||
|
||||
RenderBufferTextureHostSWGL::RenderBufferTextureHostSWGL(
|
||||
uint8_t* aBuffer, const layers::BufferDescriptor& aDescriptor)
|
||||
: mBuffer(aBuffer), mDescriptor(aDescriptor) {
|
||||
MOZ_COUNT_CTOR_INHERITED(RenderBufferTextureHostSWGL, RenderTextureHostSWGL);
|
||||
|
||||
switch (mDescriptor.type()) {
|
||||
case layers::BufferDescriptor::TYCbCrDescriptor:
|
||||
case layers::BufferDescriptor::TRGBDescriptor:
|
||||
MOZ_RELEASE_ASSERT(mBuffer != nullptr);
|
||||
break;
|
||||
default:
|
||||
gfxCriticalError() << "Bad buffer host descriptor "
|
||||
<< (int)mDescriptor.type();
|
||||
MOZ_CRASH("GFX: Bad descriptor");
|
||||
}
|
||||
}
|
||||
|
||||
RenderBufferTextureHostSWGL::~RenderBufferTextureHostSWGL() {
|
||||
MOZ_COUNT_DTOR_INHERITED(RenderBufferTextureHostSWGL, RenderTextureHostSWGL);
|
||||
}
|
||||
|
||||
size_t RenderBufferTextureHostSWGL::GetPlaneCount() {
|
||||
switch (mDescriptor.type()) {
|
||||
case layers::BufferDescriptor::TYCbCrDescriptor:
|
||||
return 3;
|
||||
default:
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
bool RenderBufferTextureHostSWGL::MapPlane(uint8_t aChannelIndex,
|
||||
PlaneInfo& aPlaneInfo) {
|
||||
switch (mDescriptor.type()) {
|
||||
case layers::BufferDescriptor::TYCbCrDescriptor: {
|
||||
const layers::YCbCrDescriptor& desc = mDescriptor.get_YCbCrDescriptor();
|
||||
aPlaneInfo.mFormat = gfx::SurfaceFormat::YUV;
|
||||
switch (aChannelIndex) {
|
||||
case 0:
|
||||
aPlaneInfo.mData =
|
||||
layers::ImageDataSerializer::GetYChannel(mBuffer, desc);
|
||||
aPlaneInfo.mStride = desc.yStride();
|
||||
aPlaneInfo.mSize = desc.ySize();
|
||||
break;
|
||||
case 1:
|
||||
aPlaneInfo.mData =
|
||||
layers::ImageDataSerializer::GetCbChannel(mBuffer, desc);
|
||||
aPlaneInfo.mStride = desc.cbCrStride();
|
||||
aPlaneInfo.mSize = desc.cbCrSize();
|
||||
break;
|
||||
case 2:
|
||||
aPlaneInfo.mData =
|
||||
layers::ImageDataSerializer::GetCrChannel(mBuffer, desc);
|
||||
aPlaneInfo.mStride = desc.cbCrStride();
|
||||
aPlaneInfo.mSize = desc.cbCrSize();
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
const layers::RGBDescriptor& desc = mDescriptor.get_RGBDescriptor();
|
||||
aPlaneInfo.mFormat = desc.format();
|
||||
aPlaneInfo.mData = mBuffer;
|
||||
aPlaneInfo.mStride = layers::ImageDataSerializer::GetRGBStride(desc);
|
||||
aPlaneInfo.mSize = desc.size();
|
||||
break;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void RenderBufferTextureHostSWGL::UnmapPlanes() {}
|
||||
|
||||
} // namespace wr
|
||||
} // namespace mozilla
|
|
@ -1,36 +0,0 @@
|
|||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
|
||||
/* 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 MOZILLA_GFX_RENDERBUFFERTEXTUREHOSTSWGL_H
|
||||
#define MOZILLA_GFX_RENDERBUFFERTEXTUREHOSTSWGL_H
|
||||
|
||||
#include "RenderTextureHostSWGL.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace wr {
|
||||
|
||||
class RenderBufferTextureHostSWGL final : public RenderTextureHostSWGL {
|
||||
public:
|
||||
RenderBufferTextureHostSWGL(uint8_t* aBuffer,
|
||||
const layers::BufferDescriptor& aDescriptor);
|
||||
|
||||
size_t GetPlaneCount() override;
|
||||
|
||||
bool MapPlane(uint8_t aChannelIndex, PlaneInfo& aPlaneInfo) override;
|
||||
|
||||
void UnmapPlanes() override;
|
||||
|
||||
private:
|
||||
virtual ~RenderBufferTextureHostSWGL();
|
||||
|
||||
uint8_t* mBuffer;
|
||||
layers::BufferDescriptor mDescriptor;
|
||||
};
|
||||
|
||||
} // namespace wr
|
||||
} // namespace mozilla
|
||||
|
||||
#endif // MOZILLA_GFX_RENDERBUFFERTEXTUREHOSTSWGL_H
|
|
@ -1,49 +0,0 @@
|
|||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
|
||||
/* 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 "RenderMacIOSurfaceTextureHostSWGL.h"
|
||||
|
||||
#include "MacIOSurfaceHelpers.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace wr {
|
||||
|
||||
RenderMacIOSurfaceTextureHostSWGL::RenderMacIOSurfaceTextureHostSWGL(
|
||||
MacIOSurface* aSurface)
|
||||
: mSurface(aSurface) {
|
||||
MOZ_COUNT_CTOR_INHERITED(RenderMacIOSurfaceTextureHostSWGL,
|
||||
RenderTextureHostSWGL);
|
||||
MOZ_RELEASE_ASSERT(mSurface);
|
||||
}
|
||||
|
||||
RenderMacIOSurfaceTextureHostSWGL::~RenderMacIOSurfaceTextureHostSWGL() {
|
||||
MOZ_COUNT_DTOR_INHERITED(RenderMacIOSurfaceTextureHostSWGL,
|
||||
RenderTextureHostSWGL);
|
||||
}
|
||||
|
||||
size_t RenderMacIOSurfaceTextureHostSWGL::GetPlaneCount() {
|
||||
size_t planeCount = mSurface->GetPlaneCount();
|
||||
return planeCount > 0 ? planeCount : 1;
|
||||
}
|
||||
|
||||
bool RenderMacIOSurfaceTextureHostSWGL::MapPlane(uint8_t aChannelIndex,
|
||||
PlaneInfo& aPlaneInfo) {
|
||||
if (!aChannelIndex) {
|
||||
mSurface->Lock();
|
||||
}
|
||||
aPlaneInfo.mFormat = mSurface->GetFormat();
|
||||
aPlaneInfo.mData = mSurface->GetBaseAddressOfPlane(aChannelIndex);
|
||||
aPlaneInfo.mStride = mSurface->GetBytesPerRow(aChannelIndex);
|
||||
aPlaneInfo.mSize =
|
||||
gfx::IntSize(mSurface->GetDevicePixelWidth(aChannelIndex),
|
||||
mSurface->GetDevicePixelHeight(aChannelIndex));
|
||||
return true;
|
||||
}
|
||||
|
||||
void RenderMacIOSurfaceTextureHostSWGL::UnmapPlanes() { mSurface->Unlock(); }
|
||||
|
||||
} // namespace wr
|
||||
} // namespace mozilla
|
|
@ -1,35 +0,0 @@
|
|||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
|
||||
/* 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 MOZILLA_GFX_RENDERMACIOSURFACETEXTUREHOSTSWGL_H
|
||||
#define MOZILLA_GFX_RENDERMACIOSURFACETEXTUREHOSTSWGL_H
|
||||
|
||||
#include "mozilla/gfx/MacIOSurface.h"
|
||||
#include "RenderTextureHostSWGL.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace wr {
|
||||
|
||||
class RenderMacIOSurfaceTextureHostSWGL final : public RenderTextureHostSWGL {
|
||||
public:
|
||||
explicit RenderMacIOSurfaceTextureHostSWGL(MacIOSurface* aSurface);
|
||||
|
||||
size_t GetPlaneCount() override;
|
||||
|
||||
bool MapPlane(uint8_t aChannelIndex, PlaneInfo& aPlaneInfo) override;
|
||||
|
||||
void UnmapPlanes() override;
|
||||
|
||||
private:
|
||||
virtual ~RenderMacIOSurfaceTextureHostSWGL();
|
||||
|
||||
RefPtr<MacIOSurface> mSurface;
|
||||
};
|
||||
|
||||
} // namespace wr
|
||||
} // namespace mozilla
|
||||
|
||||
#endif // MOZILLA_GFX_RENDERMACIOSURFACETEXTUREHOSTSWGL_H
|
|
@ -1,45 +0,0 @@
|
|||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
|
||||
/* 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 "RenderSharedSurfaceTextureHostSWGL.h"
|
||||
|
||||
#include "mozilla/layers/SourceSurfaceSharedData.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace wr {
|
||||
|
||||
RenderSharedSurfaceTextureHostSWGL::RenderSharedSurfaceTextureHostSWGL(
|
||||
gfx::SourceSurfaceSharedDataWrapper* aSurface)
|
||||
: mSurface(aSurface) {
|
||||
MOZ_COUNT_CTOR_INHERITED(RenderSharedSurfaceTextureHostSWGL,
|
||||
RenderTextureHostSWGL);
|
||||
MOZ_ASSERT(aSurface);
|
||||
}
|
||||
|
||||
RenderSharedSurfaceTextureHostSWGL::~RenderSharedSurfaceTextureHostSWGL() {
|
||||
MOZ_COUNT_DTOR_INHERITED(RenderSharedSurfaceTextureHostSWGL,
|
||||
RenderTextureHostSWGL);
|
||||
}
|
||||
|
||||
size_t RenderSharedSurfaceTextureHostSWGL::GetPlaneCount() { return 1; }
|
||||
|
||||
bool RenderSharedSurfaceTextureHostSWGL::MapPlane(uint8_t aChannelIndex,
|
||||
PlaneInfo& aPlaneInfo) {
|
||||
if (NS_WARN_IF(
|
||||
!mSurface->Map(gfx::DataSourceSurface::MapType::READ_WRITE, &mMap))) {
|
||||
return false;
|
||||
}
|
||||
aPlaneInfo.mData = mMap.mData;
|
||||
aPlaneInfo.mStride = mMap.mStride;
|
||||
aPlaneInfo.mSize = mSurface->GetSize();
|
||||
aPlaneInfo.mFormat = mSurface->GetFormat();
|
||||
return true;
|
||||
}
|
||||
|
||||
void RenderSharedSurfaceTextureHostSWGL::UnmapPlanes() { mSurface->Unmap(); }
|
||||
|
||||
} // namespace wr
|
||||
} // namespace mozilla
|
|
@ -1,45 +0,0 @@
|
|||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
|
||||
/* 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 MOZILLA_GFX_RENDERSHAREDSURFACETEXTUREHOSTSWGL_H
|
||||
#define MOZILLA_GFX_RENDERSHAREDSURFACETEXTUREHOSTSWGL_H
|
||||
|
||||
#include "RenderTextureHostSWGL.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace gfx {
|
||||
class SourceSurfaceSharedDataWrapper;
|
||||
}
|
||||
|
||||
namespace wr {
|
||||
|
||||
/**
|
||||
* This class allows for surfaces managed by SharedSurfacesParent to be inserted
|
||||
* into the render texture cache by wrapping an existing surface wrapper. These
|
||||
* surfaces are backed by BGRA/X shared memory buffers.
|
||||
*/
|
||||
class RenderSharedSurfaceTextureHostSWGL final : public RenderTextureHostSWGL {
|
||||
public:
|
||||
explicit RenderSharedSurfaceTextureHostSWGL(
|
||||
gfx::SourceSurfaceSharedDataWrapper* aSurface);
|
||||
|
||||
size_t GetPlaneCount() override;
|
||||
|
||||
bool MapPlane(uint8_t aChannelIndex, PlaneInfo& aPlaneInfo) override;
|
||||
|
||||
void UnmapPlanes() override;
|
||||
|
||||
private:
|
||||
virtual ~RenderSharedSurfaceTextureHostSWGL();
|
||||
|
||||
RefPtr<gfx::SourceSurfaceSharedDataWrapper> mSurface;
|
||||
gfx::DataSourceSurface::MappedSurface mMap;
|
||||
};
|
||||
|
||||
} // namespace wr
|
||||
} // namespace mozilla
|
||||
|
||||
#endif // MOZILLA_GFX_RENDERSHAREDSURFACETEXTUREHOSTSWGL_H
|
|
@ -41,17 +41,5 @@ bool RenderTextureHost::IsFilterUpdateNecessary(wr::ImageRendering aRendering) {
|
|||
return mCachedRendering != aRendering;
|
||||
}
|
||||
|
||||
wr::WrExternalImage RenderTextureHost::Lock(uint8_t aChannelIndex,
|
||||
gl::GLContext* aGL,
|
||||
wr::ImageRendering aRendering) {
|
||||
return InvalidToWrExternalImage();
|
||||
}
|
||||
|
||||
wr::WrExternalImage RenderTextureHost::LockSWGL(uint8_t aChannelIndex,
|
||||
void* aContext,
|
||||
wr::ImageRendering aRendering) {
|
||||
return InvalidToWrExternalImage();
|
||||
}
|
||||
|
||||
} // namespace wr
|
||||
} // namespace mozilla
|
||||
|
|
|
@ -13,7 +13,6 @@
|
|||
#include "mozilla/layers/LayersSurfaces.h"
|
||||
#include "mozilla/RefPtr.h"
|
||||
#include "mozilla/webrender/webrender_ffi.h" // for wr::ImageRendering
|
||||
#include "mozilla/webrender/WebRenderTypes.h"
|
||||
|
||||
namespace mozilla {
|
||||
|
||||
|
@ -39,15 +38,8 @@ class RenderTextureHost {
|
|||
RenderTextureHost();
|
||||
|
||||
virtual wr::WrExternalImage Lock(uint8_t aChannelIndex, gl::GLContext* aGL,
|
||||
wr::ImageRendering aRendering);
|
||||
|
||||
virtual void Unlock() {}
|
||||
|
||||
virtual wr::WrExternalImage LockSWGL(uint8_t aChannelIndex, void* aContext,
|
||||
wr::ImageRendering aRendering);
|
||||
|
||||
virtual void UnlockSWGL() {}
|
||||
|
||||
wr::ImageRendering aRendering) = 0;
|
||||
virtual void Unlock() = 0;
|
||||
virtual void ClearCachedResources() {}
|
||||
|
||||
// Called asynchronouly when corresponding TextureHost's mCompositableCount
|
||||
|
|
|
@ -1,115 +0,0 @@
|
|||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
|
||||
/* 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 "RenderTextureHostSWGL.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace wr {
|
||||
|
||||
bool RenderTextureHostSWGL::UpdatePlanes(wr::ImageRendering aRendering) {
|
||||
wr_swgl_make_current(mContext);
|
||||
size_t planeCount = GetPlaneCount();
|
||||
bool filterUpdate = IsFilterUpdateNecessary(aRendering);
|
||||
if (mPlanes.size() < planeCount) {
|
||||
mPlanes.reserve(planeCount);
|
||||
while (mPlanes.size() < planeCount) {
|
||||
mPlanes.push_back(PlaneInfo(wr_swgl_gen_texture(mContext)));
|
||||
}
|
||||
filterUpdate = true;
|
||||
}
|
||||
for (size_t i = 0; i < planeCount; i++) {
|
||||
PlaneInfo& plane = mPlanes[i];
|
||||
if (!MapPlane(i, plane)) {
|
||||
if (i > 0) {
|
||||
UnmapPlanes();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
GLenum format = 0;
|
||||
switch (plane.mFormat) {
|
||||
case gfx::SurfaceFormat::B8G8R8A8:
|
||||
case gfx::SurfaceFormat::B8G8R8X8:
|
||||
format = LOCAL_GL_RGBA8;
|
||||
break;
|
||||
case gfx::SurfaceFormat::YUV:
|
||||
format = LOCAL_GL_R8;
|
||||
break;
|
||||
case gfx::SurfaceFormat::NV12:
|
||||
format = planeCount == 2 && i > 0 ? LOCAL_GL_RG8 : LOCAL_GL_R8;
|
||||
break;
|
||||
default:
|
||||
MOZ_RELEASE_ASSERT(false, "Unhandled external image format");
|
||||
break;
|
||||
}
|
||||
wr_swgl_set_texture_buffer(mContext, plane.mTexture, format,
|
||||
plane.mSize.width, plane.mSize.height,
|
||||
plane.mStride, plane.mData, 0, 0);
|
||||
}
|
||||
if (filterUpdate) {
|
||||
mCachedRendering = aRendering;
|
||||
GLenum filter = aRendering == wr::ImageRendering::Pixelated
|
||||
? LOCAL_GL_NEAREST
|
||||
: LOCAL_GL_LINEAR;
|
||||
for (const auto& plane : mPlanes) {
|
||||
wr_swgl_set_texture_parameter(mContext, plane.mTexture,
|
||||
LOCAL_GL_TEXTURE_MIN_FILTER, filter);
|
||||
wr_swgl_set_texture_parameter(mContext, plane.mTexture,
|
||||
LOCAL_GL_TEXTURE_MAG_FILTER, filter);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
wr::WrExternalImage RenderTextureHostSWGL::LockSWGL(
|
||||
uint8_t aChannelIndex, void* aContext, wr::ImageRendering aRendering) {
|
||||
if (mContext != aContext) {
|
||||
CleanupPlanes();
|
||||
mContext = aContext;
|
||||
wr_swgl_reference_context(mContext);
|
||||
}
|
||||
if (!mContext) {
|
||||
return InvalidToWrExternalImage();
|
||||
}
|
||||
if (!mLocked) {
|
||||
if (!UpdatePlanes(aRendering)) {
|
||||
return InvalidToWrExternalImage();
|
||||
}
|
||||
mLocked = true;
|
||||
}
|
||||
if (aChannelIndex >= mPlanes.size()) {
|
||||
return InvalidToWrExternalImage();
|
||||
}
|
||||
const PlaneInfo& plane = mPlanes[aChannelIndex];
|
||||
return NativeTextureToWrExternalImage(plane.mTexture, 0, 0, plane.mSize.width,
|
||||
plane.mSize.height);
|
||||
}
|
||||
|
||||
void RenderTextureHostSWGL::UnlockSWGL() {
|
||||
if (mLocked) {
|
||||
mLocked = false;
|
||||
UnmapPlanes();
|
||||
}
|
||||
}
|
||||
|
||||
void RenderTextureHostSWGL::CleanupPlanes() {
|
||||
if (!mContext) {
|
||||
return;
|
||||
}
|
||||
if (!mPlanes.empty()) {
|
||||
wr_swgl_make_current(mContext);
|
||||
for (const auto& plane : mPlanes) {
|
||||
wr_swgl_delete_texture(mContext, plane.mTexture);
|
||||
}
|
||||
mPlanes.clear();
|
||||
}
|
||||
wr_swgl_destroy_context(mContext);
|
||||
mContext = nullptr;
|
||||
}
|
||||
|
||||
RenderTextureHostSWGL::~RenderTextureHostSWGL() { CleanupPlanes(); }
|
||||
|
||||
} // namespace wr
|
||||
} // namespace mozilla
|
|
@ -1,55 +0,0 @@
|
|||
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
|
||||
/* 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 MOZILLA_GFX_RENDERTEXTUREHOSTSWGL_H
|
||||
#define MOZILLA_GFX_RENDERTEXTUREHOSTSWGL_H
|
||||
|
||||
#include "RenderTextureHost.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace wr {
|
||||
|
||||
class RenderTextureHostSWGL : public RenderTextureHost {
|
||||
public:
|
||||
RenderTextureHostSWGL() {}
|
||||
|
||||
wr::WrExternalImage LockSWGL(uint8_t aChannelIndex, void* aContext,
|
||||
wr::ImageRendering aRendering) override;
|
||||
|
||||
void UnlockSWGL() override;
|
||||
|
||||
virtual size_t GetPlaneCount() = 0;
|
||||
|
||||
struct PlaneInfo {
|
||||
explicit PlaneInfo(GLuint aTexture) : mTexture(aTexture) {}
|
||||
|
||||
GLuint mTexture = 0;
|
||||
void* mData = nullptr;
|
||||
int32_t mStride = 0;
|
||||
gfx::IntSize mSize;
|
||||
gfx::SurfaceFormat mFormat = gfx::SurfaceFormat::UNKNOWN;
|
||||
};
|
||||
|
||||
virtual bool MapPlane(uint8_t aChannelIndex, PlaneInfo& aPlaneInfo) = 0;
|
||||
|
||||
virtual void UnmapPlanes() = 0;
|
||||
|
||||
protected:
|
||||
bool mLocked = false;
|
||||
void* mContext = nullptr;
|
||||
std::vector<PlaneInfo> mPlanes;
|
||||
|
||||
bool UpdatePlanes(wr::ImageRendering aRendering);
|
||||
|
||||
void CleanupPlanes();
|
||||
|
||||
virtual ~RenderTextureHostSWGL();
|
||||
};
|
||||
|
||||
} // namespace wr
|
||||
} // namespace mozilla
|
||||
|
||||
#endif // MOZILLA_GFX_RENDERTEXTUREHOSTSWGL_H
|
|
@ -25,7 +25,6 @@
|
|||
#include "mozilla/widget/CompositorWidget.h"
|
||||
|
||||
#ifdef XP_WIN
|
||||
# include "GLContextEGL.h"
|
||||
# include "GLLibraryEGL.h"
|
||||
# include "mozilla/widget/WinCompositorWindowThread.h"
|
||||
# include "mozilla/gfx/DeviceManagerDx.h"
|
||||
|
|
|
@ -33,16 +33,7 @@ wr::WrExternalImage wr_renderer_lock_external_image(
|
|||
<< AsUint64(aId);
|
||||
return InvalidToWrExternalImage();
|
||||
}
|
||||
if (auto* gl = renderer->gl()) {
|
||||
return texture->Lock(aChannelIndex, gl, aRendering);
|
||||
} else if (auto* swgl = renderer->swgl()) {
|
||||
return texture->LockSWGL(aChannelIndex, swgl, aRendering);
|
||||
} else {
|
||||
gfxCriticalNoteOnce
|
||||
<< "No GL or SWGL context available to lock ExternalImage for extId:"
|
||||
<< AsUint64(aId);
|
||||
return InvalidToWrExternalImage();
|
||||
}
|
||||
return texture->Lock(aChannelIndex, renderer->gl(), aRendering);
|
||||
}
|
||||
|
||||
void wr_renderer_unlock_external_image(void* aObj, wr::ExternalImageId aId,
|
||||
|
@ -53,11 +44,7 @@ void wr_renderer_unlock_external_image(void* aObj, wr::ExternalImageId aId,
|
|||
if (!texture) {
|
||||
return;
|
||||
}
|
||||
if (renderer->gl()) {
|
||||
texture->Unlock();
|
||||
} else if (renderer->swgl()) {
|
||||
texture->UnlockSWGL();
|
||||
}
|
||||
texture->Unlock();
|
||||
}
|
||||
|
||||
RendererOGL::RendererOGL(RefPtr<RenderThread>&& aThread,
|
||||
|
@ -253,8 +240,6 @@ layers::SyncObjectHost* RendererOGL::GetSyncObject() const {
|
|||
|
||||
gl::GLContext* RendererOGL::gl() const { return mCompositor->gl(); }
|
||||
|
||||
void* RendererOGL::swgl() const { return mCompositor->swgl(); }
|
||||
|
||||
void RendererOGL::SetFrameStartTime(const TimeStamp& aTime) {
|
||||
if (mFrameStartTime) {
|
||||
// frame start time is already set. This could happen when multiple
|
||||
|
|
|
@ -109,8 +109,6 @@ class RendererOGL {
|
|||
|
||||
gl::GLContext* gl() const;
|
||||
|
||||
void* swgl() const;
|
||||
|
||||
bool EnsureAsyncScreenshot();
|
||||
|
||||
protected:
|
||||
|
|
|
@ -9,7 +9,6 @@ with Files('**'):
|
|||
|
||||
EXPORTS.mozilla.webrender += [
|
||||
'RenderBufferTextureHost.h',
|
||||
'RenderBufferTextureHostSWGL.h',
|
||||
'RenderCompositor.h',
|
||||
'RenderCompositorEGL.h',
|
||||
'RenderCompositorOGL.h',
|
||||
|
@ -19,10 +18,8 @@ EXPORTS.mozilla.webrender += [
|
|||
'RendererScreenshotGrabber.h',
|
||||
'RenderExternalTextureHost.h',
|
||||
'RenderSharedSurfaceTextureHost.h',
|
||||
'RenderSharedSurfaceTextureHostSWGL.h',
|
||||
'RenderTextureHost.h',
|
||||
'RenderTextureHostOGL.h',
|
||||
'RenderTextureHostSWGL.h',
|
||||
'RenderTextureHostWrapper.h',
|
||||
'RenderThread.h',
|
||||
'webrender_ffi.h',
|
||||
|
@ -33,7 +30,6 @@ EXPORTS.mozilla.webrender += [
|
|||
UNIFIED_SOURCES += [
|
||||
'Moz2DImageRenderer.cpp',
|
||||
'RenderBufferTextureHost.cpp',
|
||||
'RenderBufferTextureHostSWGL.cpp',
|
||||
'RenderCompositor.cpp',
|
||||
'RenderCompositorEGL.cpp',
|
||||
'RenderCompositorOGL.cpp',
|
||||
|
@ -43,10 +39,8 @@ UNIFIED_SOURCES += [
|
|||
'RendererScreenshotGrabber.cpp',
|
||||
'RenderExternalTextureHost.cpp',
|
||||
'RenderSharedSurfaceTextureHost.cpp',
|
||||
'RenderSharedSurfaceTextureHostSWGL.cpp',
|
||||
'RenderTextureHost.cpp',
|
||||
'RenderTextureHostOGL.cpp',
|
||||
'RenderTextureHostSWGL.cpp',
|
||||
'RenderTextureHostWrapper.cpp',
|
||||
'RenderThread.cpp',
|
||||
'WebRenderAPI.cpp',
|
||||
|
@ -57,12 +51,10 @@ if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'cocoa':
|
|||
EXPORTS.mozilla.webrender += [
|
||||
'RenderCompositorNative.h',
|
||||
'RenderMacIOSurfaceTextureHostOGL.h',
|
||||
'RenderMacIOSurfaceTextureHostSWGL.h',
|
||||
]
|
||||
UNIFIED_SOURCES += [
|
||||
'RenderCompositorNative.cpp',
|
||||
'RenderMacIOSurfaceTextureHostOGL.cpp',
|
||||
'RenderMacIOSurfaceTextureHostSWGL.cpp',
|
||||
]
|
||||
|
||||
if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'android':
|
||||
|
|
|
@ -21,11 +21,6 @@ pub extern "C" fn wr_swgl_create_context() -> *mut c_void {
|
|||
swgl::Context::create().into()
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub extern "C" fn wr_swgl_reference_context(ctx: *mut c_void) {
|
||||
swgl::Context::from(ctx).reference();
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub extern "C" fn wr_swgl_destroy_context(ctx: *mut c_void) {
|
||||
swgl::Context::from(ctx).destroy();
|
||||
|
@ -47,50 +42,6 @@ pub extern "C" fn wr_swgl_init_default_framebuffer(
|
|||
swgl::Context::from(ctx).init_default_framebuffer(width, height, stride, buf);
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub extern "C" fn wr_swgl_gen_texture(ctx: *mut c_void) -> u32 {
|
||||
swgl::Context::from(ctx).gen_textures(1)[0]
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub extern "C" fn wr_swgl_delete_texture(ctx: *mut c_void, tex: u32) {
|
||||
swgl::Context::from(ctx).delete_textures(&[tex]);
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub extern "C" fn wr_swgl_set_texture_parameter(
|
||||
ctx: *mut c_void,
|
||||
tex: u32,
|
||||
pname: u32,
|
||||
param: i32,
|
||||
) {
|
||||
swgl::Context::from(ctx).set_texture_parameter(tex, pname, param);
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub extern "C" fn wr_swgl_set_texture_buffer(
|
||||
ctx: *mut c_void,
|
||||
tex: u32,
|
||||
internal_format: u32,
|
||||
width: i32,
|
||||
height: i32,
|
||||
stride: i32,
|
||||
buf: *mut c_void,
|
||||
min_width: i32,
|
||||
min_height: i32,
|
||||
) {
|
||||
swgl::Context::from(ctx).set_texture_buffer(
|
||||
tex,
|
||||
internal_format,
|
||||
width,
|
||||
height,
|
||||
stride,
|
||||
buf,
|
||||
min_width,
|
||||
min_height,
|
||||
);
|
||||
}
|
||||
|
||||
pub struct SwTile {
|
||||
x: i32,
|
||||
y: i32,
|
||||
|
|
|
@ -413,8 +413,7 @@ struct Program {
|
|||
macro(GL_ZERO, GL_ONE_MINUS_SRC_COLOR, 0, 0) \
|
||||
macro(GL_ZERO, GL_ONE_MINUS_SRC_COLOR, GL_ZERO, GL_ONE) \
|
||||
macro(GL_ZERO, GL_ONE_MINUS_SRC_ALPHA, 0, 0) \
|
||||
macro(GL_ZERO, GL_SRC_COLOR, 0, 0) \
|
||||
macro(GL_ONE, GL_ONE, 0, 0) \
|
||||
macro(GL_ZERO, GL_SRC_COLOR, 0, 0) macro(GL_ONE, GL_ONE, 0, 0) \
|
||||
macro(GL_ONE, GL_ONE, GL_ONE, GL_ONE_MINUS_SRC_ALPHA) \
|
||||
macro(GL_ONE, GL_ZERO, 0, 0) \
|
||||
macro(GL_ONE_MINUS_DST_ALPHA, GL_ONE, GL_ZERO, GL_ONE) \
|
||||
|
@ -513,8 +512,6 @@ struct ObjectStore {
|
|||
};
|
||||
|
||||
struct Context {
|
||||
int32_t references = 1;
|
||||
|
||||
ObjectStore<Query> queries;
|
||||
ObjectStore<Buffer> buffers;
|
||||
ObjectStore<Texture> textures;
|
||||
|
@ -1540,8 +1537,8 @@ void GenerateMipmap(UNUSED GLenum target) {
|
|||
// TODO: support mipmaps
|
||||
}
|
||||
|
||||
void SetTextureParameter(GLuint texid, GLenum pname, GLint param) {
|
||||
Texture& t = ctx->textures[texid];
|
||||
void TexParameteri(GLenum target, GLenum pname, GLint param) {
|
||||
Texture& t = ctx->textures[ctx->get_binding(target)];
|
||||
switch (pname) {
|
||||
case GL_TEXTURE_WRAP_S:
|
||||
assert(param == GL_CLAMP_TO_EDGE);
|
||||
|
@ -1560,10 +1557,6 @@ void SetTextureParameter(GLuint texid, GLenum pname, GLint param) {
|
|||
}
|
||||
}
|
||||
|
||||
void TexParameteri(GLenum target, GLenum pname, GLint param) {
|
||||
SetTextureParameter(ctx->get_binding(target), pname, param);
|
||||
}
|
||||
|
||||
void GenTextures(int n, GLuint* result) {
|
||||
for (int i = 0; i < n; i++) {
|
||||
Texture t;
|
||||
|
@ -4100,11 +4093,8 @@ void BlitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
|
|||
|
||||
void Finish() {}
|
||||
|
||||
void MakeCurrent(Context* c) {
|
||||
if (ctx == c) {
|
||||
return;
|
||||
}
|
||||
ctx = c;
|
||||
void MakeCurrent(void* ctx_ptr) {
|
||||
ctx = (Context*)ctx_ptr;
|
||||
if (ctx) {
|
||||
setup_program(ctx->current_program);
|
||||
blend_key = ctx->blend ? ctx->blend_key : BLEND_KEY_NONE;
|
||||
|
@ -4114,28 +4104,16 @@ void MakeCurrent(Context* c) {
|
|||
}
|
||||
}
|
||||
|
||||
Context* CreateContext() { return new Context; }
|
||||
void* CreateContext() { return new Context; }
|
||||
|
||||
void ReferenceContext(Context* c) {
|
||||
if (!c) {
|
||||
void DestroyContext(void* ctx_ptr) {
|
||||
if (!ctx_ptr) {
|
||||
return;
|
||||
}
|
||||
++c->references;
|
||||
}
|
||||
|
||||
void DestroyContext(Context* c) {
|
||||
if (!c) {
|
||||
return;
|
||||
}
|
||||
assert(c->references > 0);
|
||||
--c->references;
|
||||
if (c->references > 0) {
|
||||
return;
|
||||
}
|
||||
if (ctx == c) {
|
||||
if (ctx == ctx_ptr) {
|
||||
MakeCurrent(nullptr);
|
||||
}
|
||||
delete c;
|
||||
delete (Context*)ctx_ptr;
|
||||
}
|
||||
|
||||
typedef Texture LockedTexture;
|
||||
|
|
|
@ -273,7 +273,6 @@ extern "C" {
|
|||
min_width: GLsizei,
|
||||
min_height: GLsizei,
|
||||
);
|
||||
fn SetTextureParameter(tex: GLuint, pname: GLenum, param: GLint);
|
||||
fn DeleteTexture(n: GLuint);
|
||||
fn DeleteRenderbuffer(n: GLuint);
|
||||
fn DeleteFramebuffer(n: GLuint);
|
||||
|
@ -301,7 +300,6 @@ extern "C" {
|
|||
flip: GLboolean,
|
||||
);
|
||||
fn CreateContext() -> *mut c_void;
|
||||
fn ReferenceContext(ctx: *mut c_void);
|
||||
fn DestroyContext(ctx: *mut c_void);
|
||||
fn MakeCurrent(ctx: *mut c_void);
|
||||
}
|
||||
|
@ -314,12 +312,6 @@ impl Context {
|
|||
Context(unsafe { CreateContext() })
|
||||
}
|
||||
|
||||
pub fn reference(&self) {
|
||||
unsafe {
|
||||
ReferenceContext(self.0);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn destroy(&self) {
|
||||
unsafe {
|
||||
DestroyContext(self.0);
|
||||
|
@ -373,12 +365,6 @@ impl Context {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn set_texture_parameter(&self, tex: GLuint, pname: GLenum, param: GLint) {
|
||||
unsafe {
|
||||
SetTextureParameter(tex, pname, param);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn lock_framebuffer(&self, fbo: GLuint) -> Option<LockedResource> {
|
||||
unsafe {
|
||||
let resource = LockFramebuffer(fbo);
|
||||
|
|
Загрузка…
Ссылка в новой задаче