зеркало из https://github.com/mozilla/moz-skia.git
Hooks up the GrCustomStage/GrGLProgramStageFactory/GrGLProgramStage
classes from r3726 so they can be used. Does not implement any actual effect stages. Has one large known bug: if custom stages are provided, GrSamplerState comparisons will break; this should preserve correct drawing, but decrease performance - among other things, we'll break draw batching. To fix this we'll need a RTTI system for GrCustomState objects, and we'll need to change the GrSamplerState comparison from a memcmp to something that also does a deep type-sensitive compare of any GrCustomState objects present. http://codereview.appspot.com/6074043/ git-svn-id: http://skia.googlecode.com/svn/trunk@3742 2bbb7eff-a529-9590-31e7-b0007b416f81
This commit is contained in:
Родитель
5a2e879ef8
Коммит
07eecdca3e
|
@ -178,6 +178,7 @@
|
|||
'../include/gpu/GrConfig.h',
|
||||
'../include/gpu/GrContext.h',
|
||||
'../include/gpu/GrContextFactory.h',
|
||||
'../include/gpu/GrCustomStage.h',
|
||||
'../include/gpu/GrFontScaler.h',
|
||||
'../include/gpu/GrGlyph.h',
|
||||
'../include/gpu/GrInstanceCounter.h',
|
||||
|
@ -221,7 +222,6 @@
|
|||
'../src/gpu/GrClip.cpp',
|
||||
'../src/gpu/GrContext.cpp',
|
||||
'../src/gpu/GrCustomStage.cpp',
|
||||
'../src/gpu/GrCustomStage.h',
|
||||
'../src/gpu/GrDefaultPathRenderer.cpp',
|
||||
'../src/gpu/GrDefaultPathRenderer.h',
|
||||
'../src/gpu/GrDefaultTextContext.cpp',
|
||||
|
|
|
@ -8,13 +8,15 @@
|
|||
#ifndef GrCustomStage_DEFINED
|
||||
#define GrCustomStage_DEFINED
|
||||
|
||||
#include "GrRefCnt.h"
|
||||
|
||||
class GrContext;
|
||||
class GrGLProgramStageFactory;
|
||||
|
||||
/** Provides custom vertex shader, fragment shader, uniform data for a
|
||||
particular stage of the Ganesh shading pipeline.
|
||||
TODO: may want to refcount these? */
|
||||
class GrCustomStage {
|
||||
class GrCustomStage : public GrRefCnt {
|
||||
|
||||
public:
|
||||
|
|
@ -11,8 +11,9 @@
|
|||
#ifndef GrSamplerState_DEFINED
|
||||
#define GrSamplerState_DEFINED
|
||||
|
||||
#include "GrTypes.h"
|
||||
#include "GrCustomStage.h"
|
||||
#include "GrMatrix.h"
|
||||
#include "GrTypes.h"
|
||||
|
||||
#define MAX_KERNEL_WIDTH 25
|
||||
|
||||
|
@ -110,12 +111,17 @@ public:
|
|||
* unfiltered, and use identity matrix.
|
||||
*/
|
||||
GrSamplerState()
|
||||
: fRadial2CenterX1()
|
||||
: fCustomStage (NULL)
|
||||
, fRadial2CenterX1()
|
||||
, fRadial2Radius0()
|
||||
, fRadial2PosRoot() {
|
||||
this->reset();
|
||||
}
|
||||
|
||||
~GrSamplerState() {
|
||||
GrSafeUnref(fCustomStage);
|
||||
}
|
||||
|
||||
WrapMode getWrapX() const { return fWrapX; }
|
||||
WrapMode getWrapY() const { return fWrapY; }
|
||||
FilterDirection getFilterDirection() const { return fFilterDirection; }
|
||||
|
@ -188,6 +194,7 @@ public:
|
|||
fMatrix = matrix;
|
||||
fTextureDomain.setEmpty();
|
||||
fSwapRAndB = false;
|
||||
GrSafeSetNull(fCustomStage);
|
||||
}
|
||||
void reset(WrapMode wrapXAndY, Filter filter, const GrMatrix& matrix) {
|
||||
this->reset(wrapXAndY, filter, kDefault_FilterDirection, matrix);
|
||||
|
@ -236,6 +243,11 @@ public:
|
|||
fKernelWidth = radius;
|
||||
}
|
||||
|
||||
void setCustomStage(GrCustomStage* stage) {
|
||||
GrSafeAssign(fCustomStage, stage);
|
||||
}
|
||||
GrCustomStage* getCustomStage() const { return fCustomStage; }
|
||||
|
||||
private:
|
||||
WrapMode fWrapX : 8;
|
||||
WrapMode fWrapY : 8;
|
||||
|
@ -246,6 +258,12 @@ private:
|
|||
bool fSwapRAndB;
|
||||
GrRect fTextureDomain;
|
||||
|
||||
/// BUG! Ganesh only works correctly so long as fCustomStage is
|
||||
/// NULL; we need to have a complex ID system here so that we can
|
||||
/// have an equality-like comparison to determine whether two
|
||||
/// fCustomStages are equal.
|
||||
GrCustomStage* fCustomStage;
|
||||
|
||||
// these are undefined unless fSampleMode == kRadial2_SampleMode
|
||||
GrScalar fRadial2CenterX1;
|
||||
GrScalar fRadial2Radius0;
|
||||
|
|
|
@ -10,6 +10,8 @@
|
|||
#include "GrGLProgram.h"
|
||||
|
||||
#include "../GrAllocator.h"
|
||||
#include "GrCustomStage.h"
|
||||
#include "GrGLProgramStage.h"
|
||||
#include "GrGLShaderVar.h"
|
||||
#include "SkTrace.h"
|
||||
#include "SkXfermode.h"
|
||||
|
@ -620,8 +622,17 @@ const char* GrGLProgram::adjustInColor(const GrStringBuilder& inColor) const {
|
|||
}
|
||||
}
|
||||
|
||||
// If this destructor is in the header file, we must include GrGLProgramStage
|
||||
// instead of just forward-declaring it.
|
||||
GrGLProgram::CachedData::~CachedData() {
|
||||
for (int i = 0; i < GrDrawState::kNumStages; ++i) {
|
||||
delete fCustomStage[i];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool GrGLProgram::genProgram(const GrGLContextInfo& gl,
|
||||
GrCustomStage** customStages,
|
||||
GrGLProgram::CachedData* programData) const {
|
||||
|
||||
ShaderCodeSegments segments;
|
||||
|
@ -732,6 +743,21 @@ bool GrGLProgram::genProgram(const GrGLContextInfo& gl,
|
|||
}
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// Convert generic effect representation to GL-specific backend so they
|
||||
// can be accesseed in genStageCode() and in subsequent uses of
|
||||
// programData.
|
||||
for (int s = 0; s < GrDrawState::kNumStages; ++s) {
|
||||
GrCustomStage* customStage = customStages[s];
|
||||
if (NULL != customStage) {
|
||||
GrGLProgramStageFactory* factory = customStage->getGLFactory();
|
||||
programData->fCustomStage[s] =
|
||||
factory->createGLInstance(customStage);
|
||||
} else {
|
||||
programData->fCustomStage[s] = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////
|
||||
// compute the final color
|
||||
|
||||
|
@ -766,7 +792,8 @@ bool GrGLProgram::genProgram(const GrGLContextInfo& gl,
|
|||
outColor.c_str(),
|
||||
inCoords,
|
||||
&segments,
|
||||
&programData->fUniLocations.fStages[s]);
|
||||
&programData->fUniLocations.fStages[s],
|
||||
programData->fCustomStage[s]);
|
||||
inColor = outColor;
|
||||
}
|
||||
}
|
||||
|
@ -878,13 +905,14 @@ bool GrGLProgram::genProgram(const GrGLContextInfo& gl,
|
|||
inCoords = texCoordAttrs[tcIdx].c_str();
|
||||
}
|
||||
|
||||
genStageCode(gl, s,
|
||||
fProgramDesc.fStages[s],
|
||||
inCoverage.size() ? inCoverage.c_str() : NULL,
|
||||
outCoverage.c_str(),
|
||||
inCoords,
|
||||
&segments,
|
||||
&programData->fUniLocations.fStages[s]);
|
||||
this->genStageCode(gl, s,
|
||||
fProgramDesc.fStages[s],
|
||||
inCoverage.size() ? inCoverage.c_str() : NULL,
|
||||
outCoverage.c_str(),
|
||||
inCoords,
|
||||
&segments,
|
||||
&programData->fUniLocations.fStages[s],
|
||||
programData->fCustomStage[s]);
|
||||
inCoverage = outCoverage;
|
||||
}
|
||||
}
|
||||
|
@ -1348,6 +1376,11 @@ void GrGLProgram::getUniformLocationsAndInitCache(const GrGLContextInfo& gl,
|
|||
imageIncrementName.c_str()));
|
||||
GrAssert(kUnusedUniform != locations.fImageIncrementUni);
|
||||
}
|
||||
|
||||
if (NULL != programData->fCustomStage[s]) {
|
||||
programData->fCustomStage[s]->
|
||||
initUniforms(gl.interface(), progID);
|
||||
}
|
||||
}
|
||||
}
|
||||
GL_CALL(UseProgram(progID));
|
||||
|
@ -1363,6 +1396,7 @@ void GrGLProgram::getUniformLocationsAndInitCache(const GrGLContextInfo& gl,
|
|||
programData->fTextureWidth[s] = -1;
|
||||
programData->fTextureHeight[s] = -1;
|
||||
programData->fTextureDomain[s].setEmpty();
|
||||
// Must not reset fStageOverride[] here.
|
||||
}
|
||||
programData->fViewMatrix = GrMatrix::InvalidMatrix();
|
||||
programData->fColor = GrColor_ILLEGAL;
|
||||
|
@ -1712,7 +1746,8 @@ void GrGLProgram::genStageCode(const GrGLContextInfo& gl,
|
|||
const char* fsOutColor,
|
||||
const char* vsInCoord,
|
||||
ShaderCodeSegments* segments,
|
||||
StageUniLocations* locations) const {
|
||||
StageUniLocations* locations,
|
||||
GrGLProgramStage* customStage) const {
|
||||
|
||||
GrAssert(stageNum >= 0 && stageNum <= GrDrawState::kNumStages);
|
||||
GrAssert((desc.fInConfigFlags & StageDesc::kInConfigBitMask) ==
|
||||
|
@ -1723,8 +1758,13 @@ void GrGLProgram::genStageCode(const GrGLContextInfo& gl,
|
|||
// gradients.
|
||||
static const int coordDims = 2;
|
||||
int varyingDims;
|
||||
|
||||
/// Vertex Shader Stuff
|
||||
|
||||
if (NULL != customStage) {
|
||||
customStage->setupVSUnis(segments->fVSUnis, stageNum);
|
||||
}
|
||||
|
||||
// decide whether we need a matrix to transform texture coords
|
||||
// and whether the varying needs a perspective coord.
|
||||
const char* matName = NULL;
|
||||
|
@ -1808,7 +1848,20 @@ void GrGLProgram::genStageCode(const GrGLContextInfo& gl,
|
|||
&imageIncrementName, varyingVSName);
|
||||
}
|
||||
|
||||
if (NULL != customStage) {
|
||||
GrStringBuilder vertexShader;
|
||||
customStage->emitVS(&vertexShader, varyingVSName);
|
||||
segments->fVSCode.appendf("{\n");
|
||||
segments->fVSCode.append(vertexShader);
|
||||
segments->fVSCode.appendf("}\n");
|
||||
}
|
||||
|
||||
/// Fragment Shader Stuff
|
||||
|
||||
if (NULL != customStage) {
|
||||
customStage->setupFSUnis(segments->fFSUnis, stageNum);
|
||||
}
|
||||
|
||||
GrStringBuilder fsCoordName;
|
||||
// function used to access the shader, may be made projective
|
||||
GrStringBuilder texFunc("texture2D");
|
||||
|
@ -1959,6 +2012,31 @@ void GrGLProgram::genStageCode(const GrGLContextInfo& gl,
|
|||
swizzle, modulate.c_str());
|
||||
}
|
||||
}
|
||||
|
||||
if (NULL != customStage) {
|
||||
if (desc.fOptFlags & (StageDesc::kIdentityMatrix_OptFlagBit |
|
||||
StageDesc::kNoPerspective_OptFlagBit)) {
|
||||
customStage->setSamplerMode(GrGLProgramStage::kDefault_SamplerMode);
|
||||
} else if (StageDesc::kIdentity_CoordMapping == desc.fCoordMapping &&
|
||||
StageDesc::kSingle_FetchMode == desc.fFetchMode) {
|
||||
customStage->setSamplerMode(GrGLProgramStage::kProj_SamplerMode);
|
||||
} else {
|
||||
customStage->setSamplerMode(
|
||||
GrGLProgramStage::kExplicitDivide_SamplerMode);
|
||||
}
|
||||
|
||||
GrStringBuilder fragmentShader;
|
||||
fsCoordName = customStage->emitTextureSetup(
|
||||
&fragmentShader, varyingFSName,
|
||||
stageNum, coordDims, varyingDims);
|
||||
customStage->emitFS(&fragmentShader, fsOutColor, fsInColor,
|
||||
samplerName, fsCoordName.c_str());
|
||||
|
||||
// Enclose custom code in a block to avoid namespace conflicts
|
||||
segments->fFSCode.appendf("{\n");
|
||||
segments->fFSCode.append(fragmentShader);
|
||||
segments->fFSCode.appendf("}\n");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
#include "SkXfermode.h"
|
||||
|
||||
class GrBinHashKeyBuilder;
|
||||
class GrGLProgramStage;
|
||||
|
||||
struct ShaderCodeSegments;
|
||||
|
||||
|
@ -49,6 +50,7 @@ public:
|
|||
* but in a separate cacheable container.
|
||||
*/
|
||||
bool genProgram(const GrGLContextInfo& gl,
|
||||
GrCustomStage** customStages,
|
||||
CachedData* programData) const;
|
||||
|
||||
/**
|
||||
|
@ -180,6 +182,10 @@ public:
|
|||
uint8_t fCoordMapping; // casts to enum CoordMapping
|
||||
uint8_t fKernelWidth;
|
||||
|
||||
/** Non-zero if user-supplied code will write the stage's
|
||||
contribution to the fragment shader. */
|
||||
uint16_t fCustomStageKey;
|
||||
|
||||
GR_STATIC_ASSERT((InConfigFlags)(uint8_t)kInConfigBitMask ==
|
||||
kInConfigBitMask);
|
||||
|
||||
|
@ -305,10 +311,12 @@ public:
|
|||
class CachedData : public ::GrNoncopyable {
|
||||
public:
|
||||
CachedData() {
|
||||
for (int i = 0; i < GrDrawState::kNumStages; ++i) {
|
||||
fCustomStage[i] = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
~CachedData() {
|
||||
}
|
||||
~CachedData();
|
||||
|
||||
void copyAndTakeOwnership(CachedData& other) {
|
||||
memcpy(this, &other, sizeof(*this));
|
||||
|
@ -340,6 +348,8 @@ public:
|
|||
bool fRadial2PosRoot[GrDrawState::kNumStages];
|
||||
GrRect fTextureDomain[GrDrawState::kNumStages];
|
||||
|
||||
GrGLProgramStage* fCustomStage[GrDrawState::kNumStages];
|
||||
|
||||
private:
|
||||
enum Constants {
|
||||
kUniLocationPreAllocSize = 8
|
||||
|
@ -366,7 +376,8 @@ private:
|
|||
const char* fsOutColor,
|
||||
const char* vsInCoord,
|
||||
ShaderCodeSegments* segments,
|
||||
StageUniLocations* locations) const;
|
||||
StageUniLocations* locations,
|
||||
GrGLProgramStage* override) const;
|
||||
|
||||
void genGeometryShader(const GrGLContextInfo& gl,
|
||||
ShaderCodeSegments* segments) const;
|
||||
|
|
|
@ -96,8 +96,6 @@ public:
|
|||
|
||||
void setSamplerMode(SamplerMode shaderMode) { fSamplerMode = shaderMode; }
|
||||
|
||||
protected:
|
||||
|
||||
/** Returns the *effective* coord name after any perspective divide
|
||||
or other transform. */
|
||||
GrStringBuilder emitTextureSetup(GrStringBuilder* code,
|
||||
|
@ -106,6 +104,8 @@ protected:
|
|||
int coordDims,
|
||||
int varyingDims);
|
||||
|
||||
protected:
|
||||
|
||||
/** Convenience function for subclasses to write texture2D() or
|
||||
texture2DProj(), depending on fSamplerMode. */
|
||||
void emitTextureLookup(GrStringBuilder* code,
|
||||
|
@ -130,16 +130,19 @@ public:
|
|||
/** Returns a short unique identifier for this subclass x its
|
||||
parameters. If the key differs, different shader code must
|
||||
be generated; if the key matches, shader code can be reused.
|
||||
0 == no custom stage. */
|
||||
0 == no custom stage. */
|
||||
virtual uint16_t stageKey(const GrCustomStage*);
|
||||
|
||||
/** Returns a new instance of the appropriate implementation class
|
||||
for the given GrCustomStage; caller is responsible for deleting
|
||||
the object. */
|
||||
virtual GrGLProgramStage* createGLInstance(GrCustomStage*) = 0;
|
||||
|
||||
protected:
|
||||
|
||||
/** Disable default constructor - instances should be singletons
|
||||
with static factory functions: our test examples are all stateless,
|
||||
but we suspect that future implementations may want to cache data? */
|
||||
but we suspect that future implementations may want to cache data? */
|
||||
GrGLProgramStageFactory() { }
|
||||
};
|
||||
|
||||
|
|
|
@ -8,7 +8,9 @@
|
|||
|
||||
|
||||
#include "../GrBinHashKey.h"
|
||||
#include "GrCustomStage.h"
|
||||
#include "GrGLProgram.h"
|
||||
#include "GrGLProgramStage.h"
|
||||
#include "GrGLSL.h"
|
||||
#include "GrGpuGLShaders.h"
|
||||
#include "../GrGpuVertex.h"
|
||||
|
@ -82,13 +84,14 @@ public:
|
|||
}
|
||||
}
|
||||
|
||||
GrGLProgram::CachedData* getProgramData(const GrGLProgram& desc) {
|
||||
GrGLProgram::CachedData* getProgramData(const GrGLProgram& desc,
|
||||
GrCustomStage** stages) {
|
||||
Entry newEntry;
|
||||
newEntry.fKey.setKeyData(desc.keyData());
|
||||
|
||||
Entry* entry = fHashCache.find(newEntry.fKey);
|
||||
if (NULL == entry) {
|
||||
if (!desc.genProgram(fGL, &newEntry.fProgramData)) {
|
||||
if (!desc.genProgram(fGL, stages, &newEntry.fProgramData)) {
|
||||
return NULL;
|
||||
}
|
||||
if (fCount < kMaxEntries) {
|
||||
|
@ -242,6 +245,8 @@ bool GrGpuGLShaders::programUnitTest() {
|
|||
pdesc.fDualSrcOutput = ProgramDesc::kNone_DualSrcOutput;
|
||||
}
|
||||
|
||||
GrCustomStage* customStages[GrDrawState::kNumStages];
|
||||
|
||||
for (int s = 0; s < GrDrawState::kNumStages; ++s) {
|
||||
// enable the stage?
|
||||
if (random_bool(&random)) {
|
||||
|
@ -288,9 +293,13 @@ bool GrGpuGLShaders::programUnitTest() {
|
|||
stage.fInConfigFlags &= ~kMulByAlphaMask;
|
||||
break;
|
||||
}
|
||||
|
||||
stage.fCustomStageKey = 0;
|
||||
customStages[s] = NULL;
|
||||
}
|
||||
CachedData cachedData;
|
||||
if (!program.genProgram(this->glContextInfo(), &cachedData)) {
|
||||
if (!program.genProgram(this->glContextInfo(), customStages,
|
||||
&cachedData)) {
|
||||
return false;
|
||||
}
|
||||
DeleteProgram(this->glInterface(), &cachedData);
|
||||
|
@ -772,8 +781,10 @@ bool GrGpuGLShaders::flushGraphicsState(GrPrimitiveType type) {
|
|||
return false;
|
||||
}
|
||||
|
||||
this->buildProgram(type, blendOpts, dstCoeff);
|
||||
fProgramData = fProgramCache->getProgramData(fCurrentProgram);
|
||||
GrCustomStage* customStages [GrDrawState::kNumStages];
|
||||
this->buildProgram(type, blendOpts, dstCoeff, customStages);
|
||||
fProgramData = fProgramCache->getProgramData(fCurrentProgram,
|
||||
customStages);
|
||||
if (NULL == fProgramData) {
|
||||
GrAssert(!"Failed to create program!");
|
||||
return false;
|
||||
|
@ -814,6 +825,13 @@ bool GrGpuGLShaders::flushGraphicsState(GrPrimitiveType type) {
|
|||
this->flushTexelSize(s);
|
||||
|
||||
this->flushTextureDomain(s);
|
||||
|
||||
if (NULL != fProgramData->fCustomStage[s]) {
|
||||
const GrSamplerState& sampler =
|
||||
this->getDrawState().getSampler(s);
|
||||
fProgramData->fCustomStage[s]->setData(
|
||||
this->glInterface(), sampler.getCustomStage());
|
||||
}
|
||||
}
|
||||
}
|
||||
this->flushEdgeAAData();
|
||||
|
@ -962,9 +980,29 @@ void GrGpuGLShaders::setupGeometry(int* startVertex,
|
|||
fHWGeometryState.fArrayPtrsDirty = false;
|
||||
}
|
||||
|
||||
namespace {
|
||||
|
||||
void setup_custom_stage(GrGLProgram::ProgramDesc::StageDesc* stage,
|
||||
const GrSamplerState& sampler,
|
||||
GrCustomStage** customStages,
|
||||
GrGLProgram* program, int index) {
|
||||
GrCustomStage* customStage = sampler.getCustomStage();
|
||||
if (customStage) {
|
||||
GrGLProgramStageFactory* factory = customStage->getGLFactory();
|
||||
stage->fCustomStageKey = factory->stageKey(customStage);
|
||||
customStages[index] = customStage;
|
||||
} else {
|
||||
stage->fCustomStageKey = 0;
|
||||
customStages[index] = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void GrGpuGLShaders::buildProgram(GrPrimitiveType type,
|
||||
BlendOptFlags blendOpts,
|
||||
GrBlendCoeff dstCoeff) {
|
||||
GrBlendCoeff dstCoeff,
|
||||
GrCustomStage** customStages) {
|
||||
ProgramDesc& desc = fCurrentProgram.fProgramDesc;
|
||||
const GrDrawState& drawState = this->getDrawState();
|
||||
|
||||
|
@ -1170,12 +1208,18 @@ void GrGpuGLShaders::buildProgram(GrPrimitiveType type,
|
|||
} else {
|
||||
stage.fKernelWidth = 0;
|
||||
}
|
||||
|
||||
setup_custom_stage(&stage, sampler, customStages,
|
||||
&fCurrentProgram, s);
|
||||
|
||||
} else {
|
||||
stage.fOptFlags = 0;
|
||||
stage.fCoordMapping = (StageDesc::CoordMapping) 0;
|
||||
stage.fInConfigFlags = 0;
|
||||
stage.fFetchMode = (StageDesc::FetchMode) 0;
|
||||
stage.fKernelWidth = 0;
|
||||
stage.fCustomStageKey = 0;
|
||||
customStages[s] = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -14,6 +14,7 @@
|
|||
#include "GrGpuGL.h"
|
||||
#include "GrGLProgram.h"
|
||||
|
||||
class GrCustomStage;
|
||||
class GrGpuGLProgram;
|
||||
|
||||
// Programmable OpenGL or OpenGL ES 2.0
|
||||
|
@ -86,7 +87,8 @@ private:
|
|||
|
||||
void buildProgram(GrPrimitiveType typeBlend,
|
||||
BlendOptFlags blendOpts,
|
||||
GrBlendCoeff dstCoeff);
|
||||
GrBlendCoeff dstCoeff,
|
||||
GrCustomStage** customStages);
|
||||
|
||||
ProgramCache* fProgramCache;
|
||||
CachedData* fProgramData;
|
||||
|
|
Загрузка…
Ссылка в новой задаче