/*
- * Copyright (c) 2023 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2024 Samsung Electronics Co., Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
*/
#include "test-graphics-texture.h"
+#include <dali/integration-api/pixel-data-integ.h>
#include <iostream>
#include <sstream>
updateInfo.srcExtent2D.width != (mCreateInfo.size.width / (1 << updateInfo.level)) ||
updateInfo.srcExtent2D.height != (mCreateInfo.size.height / (1 << updateInfo.level)));
+ uint8_t* pixels = nullptr;
+ bool releasePixels = false;
+
+ switch(source.sourceType)
+ {
+ case Graphics::TextureUpdateSourceInfo::Type::PIXEL_DATA:
+ {
+ auto pixelDataBuffer = Dali::Integration::GetPixelDataBuffer(source.pixelDataSource.pixelData);
+
+ pixels = pixelDataBuffer.buffer;
+ releasePixels = Dali::Integration::IsPixelDataReleaseAfterUpload(source.pixelDataSource.pixelData) && updateInfo.srcOffset == 0u;
+ break;
+ }
+ case Graphics::TextureUpdateSourceInfo::Type::MEMORY:
+ {
+ pixels = reinterpret_cast<uint8_t*>(source.memorySource.memory);
+ releasePixels = true;
+ break;
+ }
+ default:
+ {
+ // TODO : Implement here
+ break;
+ }
+ }
+
if(!isSubImage)
{
if(!mIsCompressed)
{
- mGlAbstraction.TexImage2D(target, updateInfo.level, mGlInternalFormat, updateInfo.srcExtent2D.width, updateInfo.srcExtent2D.height, 0, mGlFormat, mPixelDataType, source.memorySource.memory);
+ mGlAbstraction.TexImage2D(target, updateInfo.level, mGlInternalFormat, updateInfo.srcExtent2D.width, updateInfo.srcExtent2D.height, 0, mGlFormat, mPixelDataType, pixels);
}
else
{
- mGlAbstraction.CompressedTexImage2D(target, updateInfo.level, mGlInternalFormat, updateInfo.srcExtent2D.width, updateInfo.srcExtent2D.height, 0, updateInfo.srcSize, source.memorySource.memory);
+ mGlAbstraction.CompressedTexImage2D(target, updateInfo.level, mGlInternalFormat, updateInfo.srcExtent2D.width, updateInfo.srcExtent2D.height, 0, updateInfo.srcSize, pixels);
}
}
else
{
if(!mIsCompressed)
{
- mGlAbstraction.TexSubImage2D(target, updateInfo.level, updateInfo.dstOffset2D.x, updateInfo.dstOffset2D.y, updateInfo.srcExtent2D.width, updateInfo.srcExtent2D.height, mGlFormat, mPixelDataType, source.memorySource.memory);
+ mGlAbstraction.TexSubImage2D(target, updateInfo.level, updateInfo.dstOffset2D.x, updateInfo.dstOffset2D.y, updateInfo.srcExtent2D.width, updateInfo.srcExtent2D.height, mGlFormat, mPixelDataType, pixels);
}
else
{
- mGlAbstraction.CompressedTexSubImage2D(target, updateInfo.level, updateInfo.dstOffset2D.x, updateInfo.dstOffset2D.y, updateInfo.srcExtent2D.width, updateInfo.srcExtent2D.height, mGlFormat, updateInfo.srcSize, source.memorySource.memory);
+ mGlAbstraction.CompressedTexSubImage2D(target, updateInfo.level, updateInfo.dstOffset2D.x, updateInfo.dstOffset2D.y, updateInfo.srcExtent2D.width, updateInfo.srcExtent2D.height, mGlFormat, updateInfo.srcSize, pixels);
+ }
+ }
+
+ if(releasePixels && pixels != nullptr)
+ {
+ switch(source.sourceType)
+ {
+ case Graphics::TextureUpdateSourceInfo::Type::PIXEL_DATA:
+ {
+ Dali::Integration::ReleasePixelDataBuffer(source.pixelDataSource.pixelData);
+ break;
+ }
+ case Graphics::TextureUpdateSourceInfo::Type::MEMORY:
+ {
+ free(reinterpret_cast<void*>(pixels));
+ break;
+ }
+ default:
+ {
+ // TODO : Implement here
+ break;
+ }
}
}
}
// Connect to actor's touched signal
SignalData data;
- TouchEventFunctor functor(data, false /* Do not consume */);
+ TouchEventFunctor functor(data); // consume
actor.TouchedSignal().Connect(&application, functor);
// Connect to parent's touched signal
DALI_TEST_CHECK(parent == interceptData.touchedActor);
DALI_TEST_EQUALS(true, parentData.functorCalled, TEST_LOCATION);
DALI_TEST_EQUALS(PointState::DOWN, parentData.receivedTouch.points[0].state, TEST_LOCATION);
- DALI_TEST_CHECK(parent == parentData.receivedTouch.points[0].hitActor);
+ DALI_TEST_CHECK(actor == parentData.receivedTouch.points[0].hitActor);
DALI_TEST_CHECK(parent == parentData.touchedActor);
data.Reset();
interceptData.Reset();
#include <dali/devel-api/actors/actor-devel.h>
#include <dali/devel-api/events/long-press-gesture-detector-devel.h>
#include <dali/integration-api/events/touch-event-integ.h>
+#include <dali/integration-api/events/touch-integ.h>
#include <dali/integration-api/input-options.h>
#include <dali/integration-api/render-task-list-integ.h>
+#include <dali/internal/event/events/touch-event-impl.h>
+#include <dali/internal/event/render-tasks/render-task-impl.h>
#include <dali/public-api/dali-core.h>
#include <stdlib.h>
#include <test-touch-event-utils.h>
}
};
+Integration::TouchEvent GenerateSingleTouch(PointState::Type state, const Vector2& screenPosition, uint32_t time)
+{
+ Integration::TouchEvent touchEvent;
+ Integration::Point point;
+ point.SetState(state);
+ point.SetDeviceId(4);
+ point.SetScreenPosition(screenPosition);
+ point.SetDeviceClass(Device::Class::TOUCH);
+ point.SetDeviceSubclass(Device::Subclass::NONE);
+ touchEvent.points.push_back(point);
+ touchEvent.time = time;
+ return touchEvent;
+}
} // namespace
///////////////////////////////////////////////////////////////////////////////
END_TEST;
}
+
+int UtcDaliLongPressGestureFeedTouch(void)
+{
+ TestApplication application;
+ Integration::Scene scene = application.GetScene();
+ RenderTaskList taskList = scene.GetRenderTaskList();
+ Dali::RenderTask task = taskList.GetTask(0);
+
+ Actor parentActor = Actor::New();
+ parentActor.SetProperty(Actor::Property::SIZE, Vector2(100.0f, 100.0f));
+ parentActor.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
+
+ Actor childActor = Actor::New();
+ childActor.SetProperty(Actor::Property::SIZE, Vector2(100.0f, 100.0f));
+ childActor.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
+
+ parentActor.Add(childActor);
+ application.GetScene().Add(parentActor);
+
+ // Render and notify
+ application.SendNotification();
+ application.Render();
+
+ SignalData pData;
+ GestureReceivedFunctor pFunctor(pData);
+
+ LongPressGestureDetector parentDetector = LongPressGestureDetector::New();
+ parentDetector.DetectedSignal().Connect(&application, pFunctor);
+
+ Integration::TouchEvent tp = GenerateSingleTouch(PointState::DOWN, Vector2(50.0f, 50.0f), 100);
+ Internal::TouchEventPtr touchEventImpl(new Internal::TouchEvent(100));
+ touchEventImpl->AddPoint(tp.GetPoint(0));
+ touchEventImpl->SetRenderTask(task);
+ Dali::TouchEvent touchEventHandle(touchEventImpl.Get());
+ parentDetector.FeedTouch(parentActor, touchEventHandle);
+
+ TestTriggerLongPress(application);
+
+ tp = GenerateSingleTouch(PointState::UP, Vector2(50.0f, 50.0f), 150);
+ touchEventImpl = new Internal::TouchEvent(150);
+ touchEventImpl->AddPoint(tp.GetPoint(0));
+ touchEventImpl->SetRenderTask(task);
+ touchEventHandle = Dali::TouchEvent(touchEventImpl.Get());
+ parentDetector.FeedTouch(parentActor, touchEventHandle);
+
+ DALI_TEST_EQUALS(true, pData.functorCalled, TEST_LOCATION);
+ pData.Reset();
+
+ END_TEST;
+}
#include <dali/devel-api/actors/actor-devel.h>
#include <dali/devel-api/events/pan-gesture-devel.h>
#include <dali/integration-api/events/touch-event-integ.h>
+#include <dali/integration-api/events/touch-integ.h>
#include <dali/integration-api/input-options.h>
#include <dali/integration-api/profiling.h>
#include <dali/integration-api/render-task-list-integ.h>
+#include <dali/internal/event/events/touch-event-impl.h>
+#include <dali/internal/event/render-tasks/render-task-impl.h>
#include <dali/public-api/dali-core.h>
#include <stdlib.h>
#include <test-touch-event-utils.h>
return pan;
}
+Integration::TouchEvent GenerateSingleTouch(PointState::Type state, const Vector2& screenPosition, uint32_t time)
+{
+ Integration::TouchEvent touchEvent;
+ Integration::Point point;
+ point.SetState(state);
+ point.SetDeviceId(4);
+ point.SetScreenPosition(screenPosition);
+ point.SetDeviceClass(Device::Class::TOUCH);
+ point.SetDeviceSubclass(Device::Subclass::NONE);
+ touchEvent.points.push_back(point);
+ touchEvent.time = time;
+ return touchEvent;
+}
} // namespace
///////////////////////////////////////////////////////////////////////////////
END_TEST;
}
+
+int UtcDaliPanGestureFeedTouch(void)
+{
+ TestApplication application;
+ Integration::Scene scene = application.GetScene();
+ RenderTaskList taskList = scene.GetRenderTaskList();
+ Dali::RenderTask task = taskList.GetTask(0);
+
+ Actor parentActor = Actor::New();
+ parentActor.SetProperty(Actor::Property::SIZE, Vector2(100.0f, 100.0f));
+ parentActor.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
+
+ Actor childActor = Actor::New();
+ childActor.SetProperty(Actor::Property::SIZE, Vector2(100.0f, 100.0f));
+ childActor.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
+
+ parentActor.Add(childActor);
+ application.GetScene().Add(parentActor);
+
+ // Render and notify
+ application.SendNotification();
+ application.Render();
+
+ SignalData pData;
+ GestureReceivedFunctor pFunctor(pData);
+
+ PanGestureDetector parentDetector = PanGestureDetector::New();
+ parentDetector.DetectedSignal().Connect(&application, pFunctor);
+
+
+ Integration::TouchEvent tp = GenerateSingleTouch(PointState::DOWN, Vector2(50.0f, 50.0f), 100);
+ Internal::TouchEventPtr touchEventImpl(new Internal::TouchEvent(100));
+ touchEventImpl->AddPoint(tp.GetPoint(0));
+ touchEventImpl->SetRenderTask(task);
+ Dali::TouchEvent touchEventHandle(touchEventImpl.Get());
+ parentDetector.FeedTouch(parentActor, touchEventHandle);
+
+
+ tp = GenerateSingleTouch(PointState::MOTION, Vector2(70.0f, 70.0f), 150);
+ touchEventImpl = new Internal::TouchEvent(150);
+ touchEventImpl->AddPoint(tp.GetPoint(0));
+ touchEventImpl->SetRenderTask(task);
+ touchEventHandle = Dali::TouchEvent(touchEventImpl.Get());
+ parentDetector.FeedTouch(parentActor, touchEventHandle);
+
+
+ tp = GenerateSingleTouch(PointState::MOTION, Vector2(90.0f, 90.0f), 200);
+ touchEventImpl = new Internal::TouchEvent(200);
+ touchEventImpl->AddPoint(tp.GetPoint(0));
+ touchEventImpl->SetRenderTask(task);
+ touchEventHandle = Dali::TouchEvent(touchEventImpl.Get());
+ parentDetector.FeedTouch(parentActor, touchEventHandle);
+
+ tp = GenerateSingleTouch(PointState::UP, Vector2(100.0f, 100.0f), 250);
+ touchEventImpl = new Internal::TouchEvent(250);
+ touchEventImpl->AddPoint(tp.GetPoint(0));
+ touchEventImpl->SetRenderTask(task);
+ touchEventHandle = Dali::TouchEvent(touchEventImpl.Get());
+ parentDetector.FeedTouch(parentActor, touchEventHandle);
+
+
+ DALI_TEST_EQUALS(true, pData.functorCalled, TEST_LOCATION);
+ pData.Reset();
+
+ END_TEST;
+}
#include <dali-test-suite-utils.h>
#include <dali/devel-api/actors/actor-devel.h>
#include <dali/integration-api/events/touch-event-integ.h>
+#include <dali/integration-api/events/touch-integ.h>
#include <dali/integration-api/render-task-list-integ.h>
+#include <dali/internal/event/events/touch-event-impl.h>
+#include <dali/internal/event/render-tasks/render-task-impl.h>
#include <dali/public-api/dali-core.h>
#include <stdlib.h>
#include <test-touch-event-utils.h>
Integration::Scene scene;
};
+
+Integration::TouchEvent GenerateDoubleTouch(PointState::Type stateA, const Vector2& screenPositionA, PointState::Type stateB, const Vector2& screenPositionB, uint32_t time)
+{
+ Integration::TouchEvent touchEvent;
+ Integration::Point point;
+ point.SetState(stateA);
+ point.SetScreenPosition(screenPositionA);
+ point.SetDeviceClass(Device::Class::TOUCH);
+ point.SetDeviceSubclass(Device::Subclass::NONE);
+ touchEvent.points.push_back(point);
+ point.SetScreenPosition(screenPositionB);
+ point.SetState(stateB);
+ touchEvent.points.push_back(point);
+ touchEvent.time = time;
+ return touchEvent;
+}
+
} // namespace
///////////////////////////////////////////////////////////////////////////////
pData.Reset();
END_TEST;
-}
\ No newline at end of file
+}
+
+int UtcDaliPinchGestureFeedTouch(void)
+{
+ TestApplication application;
+ Integration::Scene scene = application.GetScene();
+ RenderTaskList taskList = scene.GetRenderTaskList();
+ Dali::RenderTask task = taskList.GetTask(0);
+
+ Actor parentActor = Actor::New();
+ parentActor.SetProperty(Actor::Property::SIZE, Vector2(100.0f, 100.0f));
+ parentActor.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
+
+ Actor childActor = Actor::New();
+ childActor.SetProperty(Actor::Property::SIZE, Vector2(100.0f, 100.0f));
+ childActor.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
+
+ parentActor.Add(childActor);
+ application.GetScene().Add(parentActor);
+
+ // Render and notify
+ application.SendNotification();
+ application.Render();
+
+ SignalData pData;
+ GestureReceivedFunctor pFunctor(pData);
+
+ PinchGestureDetector parentDetector = PinchGestureDetector::New();
+ parentDetector.DetectedSignal().Connect(&application, pFunctor);
+
+ Integration::TouchEvent tp = GenerateDoubleTouch(PointState::DOWN, Vector2(2.0f, 20.0f), PointState::DOWN, Vector2(38.0f, 20.0f), 100);
+ Internal::TouchEventPtr touchEventImpl(new Internal::TouchEvent(100));
+ touchEventImpl->AddPoint(tp.GetPoint(0));
+ touchEventImpl->AddPoint(tp.GetPoint(1));
+ touchEventImpl->SetRenderTask(task);
+ Dali::TouchEvent touchEventHandle(touchEventImpl.Get());
+ parentDetector.FeedTouch(parentActor, touchEventHandle);
+
+ tp = GenerateDoubleTouch(PointState::MOTION, Vector2(10.0f, 20.0f), PointState::MOTION, Vector2(30.0f, 20.0f), 150);
+ touchEventImpl = new Internal::TouchEvent(150);
+ touchEventImpl->AddPoint(tp.GetPoint(0));
+ touchEventImpl->AddPoint(tp.GetPoint(1));
+ touchEventImpl->SetRenderTask(task);
+ touchEventHandle = Dali::TouchEvent(touchEventImpl.Get());
+ parentDetector.FeedTouch(parentActor, touchEventHandle);
+
+ tp = GenerateDoubleTouch(PointState::MOTION, Vector2(10.0f, 20.0f), PointState::MOTION, Vector2(30.0f, 20.0f), 200);
+ touchEventImpl = new Internal::TouchEvent(200);
+ touchEventImpl->AddPoint(tp.GetPoint(0));
+ touchEventImpl->AddPoint(tp.GetPoint(1));
+ touchEventImpl->SetRenderTask(task);
+ touchEventHandle = Dali::TouchEvent(touchEventImpl.Get());
+ parentDetector.FeedTouch(parentActor, touchEventHandle);
+
+ tp = GenerateDoubleTouch(PointState::MOTION, Vector2(10.0f, 20.0f), PointState::MOTION, Vector2(30.0f, 20.0f), 250);
+ touchEventImpl = new Internal::TouchEvent(250);
+ touchEventImpl->AddPoint(tp.GetPoint(0));
+ touchEventImpl->AddPoint(tp.GetPoint(1));
+ touchEventImpl->SetRenderTask(task);
+ touchEventHandle = Dali::TouchEvent(touchEventImpl.Get());
+ parentDetector.FeedTouch(parentActor, touchEventHandle);
+
+ tp = GenerateDoubleTouch(PointState::MOTION, Vector2(10.0f, 20.0f), PointState::MOTION, Vector2(30.0f, 20.0f), 300);
+ touchEventImpl = new Internal::TouchEvent(300);
+ touchEventImpl->AddPoint(tp.GetPoint(0));
+ touchEventImpl->AddPoint(tp.GetPoint(1));
+ touchEventImpl->SetRenderTask(task);
+ touchEventHandle = Dali::TouchEvent(touchEventImpl.Get());
+ parentDetector.FeedTouch(parentActor, touchEventHandle);
+
+ tp = GenerateDoubleTouch(PointState::UP, Vector2(10.0f, 20.0f), PointState::UP, Vector2(30.0f, 20.0f), 350);
+ touchEventImpl = new Internal::TouchEvent(350);
+ touchEventImpl->AddPoint(tp.GetPoint(0));
+ touchEventImpl->AddPoint(tp.GetPoint(1));
+ touchEventImpl->SetRenderTask(task);
+ touchEventHandle = Dali::TouchEvent(touchEventImpl.Get());
+ parentDetector.FeedTouch(parentActor, touchEventHandle);
+
+
+ DALI_TEST_EQUALS(true, pData.functorCalled, TEST_LOCATION);
+ pData.Reset();
+
+ END_TEST;
+}
/*
- * Copyright (c) 2023 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2024 Samsung Electronics Co., Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
END_TEST;
}
-int UtcDaliPixelDataReleasePixelDataBuffer(void)
+int UtcDaliPixelDataGetPixelDataBuffer(void)
{
TestApplication application;
DALI_TEST_CHECK(pixelData.GetStride() == stride);
DALI_TEST_CHECK(pixelData.GetPixelFormat() == Pixel::L8);
- Dali::Integration::PixelDataBuffer pixelDataBuffer = Dali::Integration::ReleasePixelDataBuffer(pixelData);
+ Dali::Integration::PixelDataBuffer pixelDataBuffer = Dali::Integration::GetPixelDataBuffer(pixelData);
- DALI_TEST_CHECK(!pixelData);
+ DALI_TEST_CHECK(pixelData);
DALI_TEST_EQUALS(pixelDataBuffer.bufferSize, bufferSize, TEST_LOCATION);
DALI_TEST_EQUALS(pixelDataBuffer.buffer[0], static_cast<uint8_t>('a'), TEST_LOCATION);
- // Release memory by our self.
- delete[] pixelDataBuffer.buffer;
-
END_TEST;
}
-int UtcDaliPixelDataGetPixelDataBuffer(void)
+int UtcDaliPixelDataReleasePixelDataBuffer(void)
{
TestApplication application;
DALI_TEST_CHECK(pixelData.GetStride() == stride);
DALI_TEST_CHECK(pixelData.GetPixelFormat() == Pixel::L8);
+ Dali::Integration::ReleasePixelDataBuffer(pixelData);
+
Dali::Integration::PixelDataBuffer pixelDataBuffer = Dali::Integration::GetPixelDataBuffer(pixelData);
+ DALI_TEST_CHECK(pixelDataBuffer.buffer == nullptr);
+
+ END_TEST;
+}
+
+int UtcDaliPixelDataNewPixelDataWithReleaseAfterUpload(void)
+{
+ TestApplication application;
+
+ uint32_t width = 10u;
+ uint32_t height = 10u;
+ uint32_t stride = 12u;
+ uint32_t bufferSize = stride * height * Pixel::GetBytesPerPixel(Pixel::L8);
+ uint8_t* buffer = new uint8_t[bufferSize];
+ buffer[0] = 'a';
+
+ PixelData pixelData = Dali::Integration::NewPixelDataWithReleaseAfterUpload(buffer, bufferSize, width, height, stride, Pixel::L8, PixelData::DELETE_ARRAY);
+
DALI_TEST_CHECK(pixelData);
+ DALI_TEST_CHECK(pixelData.GetWidth() == width);
+ DALI_TEST_CHECK(pixelData.GetHeight() == height);
+ DALI_TEST_CHECK(pixelData.GetStride() == stride);
+ DALI_TEST_CHECK(pixelData.GetPixelFormat() == Pixel::L8);
+ DALI_TEST_EQUALS(Dali::Integration::IsPixelDataReleaseAfterUpload(pixelData), true, TEST_LOCATION);
+
+ Dali::Integration::PixelDataBuffer pixelDataBuffer = Dali::Integration::GetPixelDataBuffer(pixelData);
DALI_TEST_EQUALS(pixelDataBuffer.bufferSize, bufferSize, TEST_LOCATION);
DALI_TEST_EQUALS(pixelDataBuffer.buffer[0], static_cast<uint8_t>('a'), TEST_LOCATION);
END_TEST;
}
+int UtcDaliPropertyNotificationStepQuaternion(void)
+{
+ TestApplication application;
+ tet_infoline(" UtcDaliPropertyNotificationStepQuaternion");
+
+ tet_printf("Note : Current implement is kind of POC. Should be complete in future.");
+
+ Actor actor = Actor::New();
+ application.GetScene().Add(actor);
+
+ // TODO : Need to be meanful value in future.
+ const float tinyStep = 0.01f;
+
+ PropertyNotification notification = actor.AddPropertyNotification(Actor::Property::ORIENTATION, StepCondition(tinyStep));
+ notification.NotifySignal().Connect(&TestCallback);
+
+ // Rotate big angles for current case.
+ actor.SetProperty(Actor::Property::ORIENTATION, Quaternion(Radian(Degree(0.0f)), Vector3::YAXIS));
+ Wait(application, DEFAULT_WAIT_PERIOD);
+
+ for(int i = 1; i <= 10; ++i)
+ {
+ // Move x to negative position
+ gCallBackCalled = false;
+ actor.SetProperty(Actor::Property::ORIENTATION, Quaternion(Radian(Degree(i * 36.0f)), Vector3::YAXIS));
+ Wait(application, DEFAULT_WAIT_PERIOD);
+ DALI_TEST_CHECK(gCallBackCalled);
+ }
+
+ tet_printf("Test for length of EulerAngle is same, but each componets are difference.");
+ actor.SetProperty(Actor::Property::ORIENTATION, Quaternion(Radian(Degree(90.0f)), Vector3::YAXIS));
+ Wait(application, DEFAULT_WAIT_PERIOD);
+
+ gCallBackCalled = false;
+ actor.SetProperty(Actor::Property::ORIENTATION, Quaternion(Radian(Degree(90.0f)), Vector3::XAXIS));
+ Wait(application, DEFAULT_WAIT_PERIOD);
+ DALI_TEST_CHECK(gCallBackCalled);
+
+ tet_printf("Test notify should not be called");
+ gCallBackCalled = false;
+ Animation animation = Animation::New(RENDER_FRAME_INTERVAL);
+ animation.AnimateTo(Property(actor, Actor::Property::ORIENTATION), Quaternion(Radian(Degree(90.0f)), Vector3::XAXIS));
+ animation.Play();
+
+ application.SendNotification();
+ application.Render(RENDER_FRAME_INTERVAL);
+ application.SendNotification();
+ application.Render(RENDER_FRAME_INTERVAL);
+
+ DALI_TEST_CHECK(!gCallBackCalled);
+ END_TEST;
+}
+
int UtcDaliPropertyNotificationVariableStep(void)
{
TestApplication application;
#include <dali-test-suite-utils.h>
#include <dali/devel-api/actors/actor-devel.h>
#include <dali/integration-api/events/touch-event-integ.h>
+#include <dali/integration-api/events/touch-integ.h>
#include <dali/integration-api/render-task-list-integ.h>
+#include <dali/internal/event/events/touch-event-impl.h>
+#include <dali/internal/event/render-tasks/render-task-impl.h>
#include <dali/public-api/dali-core.h>
#include <stdlib.h>
#include <test-touch-event-utils.h>
Integration::Scene scene;
};
+Integration::TouchEvent GenerateDoubleTouch(PointState::Type stateA, const Vector2& screenPositionA, PointState::Type stateB, const Vector2& screenPositionB, uint32_t time)
+{
+ Integration::TouchEvent touchEvent;
+ Integration::Point point;
+ point.SetState(stateA);
+ point.SetScreenPosition(screenPositionA);
+ point.SetDeviceClass(Device::Class::TOUCH);
+ point.SetDeviceSubclass(Device::Subclass::NONE);
+ touchEvent.points.push_back(point);
+ point.SetScreenPosition(screenPositionB);
+ point.SetState(stateB);
+ touchEvent.points.push_back(point);
+ touchEvent.time = time;
+ return touchEvent;
+}
} // namespace
///////////////////////////////////////////////////////////////////////////////
pData.Reset();
END_TEST;
-}
\ No newline at end of file
+}
+
+
+int UtcDaliRotationGestureFeedTouch(void)
+{
+ TestApplication application;
+ Integration::Scene scene = application.GetScene();
+ RenderTaskList taskList = scene.GetRenderTaskList();
+ Dali::RenderTask task = taskList.GetTask(0);
+
+ Actor parentActor = Actor::New();
+ parentActor.SetProperty(Actor::Property::SIZE, Vector2(100.0f, 100.0f));
+ parentActor.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
+
+ Actor childActor = Actor::New();
+ childActor.SetProperty(Actor::Property::SIZE, Vector2(100.0f, 100.0f));
+ childActor.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
+
+ parentActor.Add(childActor);
+ application.GetScene().Add(parentActor);
+
+ // Render and notify
+ application.SendNotification();
+ application.Render();
+
+ SignalData pData;
+ GestureReceivedFunctor pFunctor(pData);
+
+ RotationGestureDetector parentDetector = RotationGestureDetector::New();
+ parentDetector.DetectedSignal().Connect(&application, pFunctor);
+
+ Integration::TouchEvent tp = GenerateDoubleTouch(PointState::DOWN, Vector2(2.0f, 20.0f), PointState::DOWN, Vector2(38.0f, 20.0f), 100);
+ Internal::TouchEventPtr touchEventImpl(new Internal::TouchEvent(100));
+ touchEventImpl->AddPoint(tp.GetPoint(0));
+ touchEventImpl->AddPoint(tp.GetPoint(1));
+ touchEventImpl->SetRenderTask(task);
+ Dali::TouchEvent touchEventHandle(touchEventImpl.Get());
+ parentDetector.FeedTouch(parentActor, touchEventHandle);
+
+ tp = GenerateDoubleTouch(PointState::MOTION, Vector2(10.0f, 20.0f), PointState::MOTION, Vector2(30.0f, 20.0f), 150);
+ touchEventImpl = new Internal::TouchEvent(150);
+ touchEventImpl->AddPoint(tp.GetPoint(0));
+ touchEventImpl->AddPoint(tp.GetPoint(1));
+ touchEventImpl->SetRenderTask(task);
+ touchEventHandle = Dali::TouchEvent(touchEventImpl.Get());
+ parentDetector.FeedTouch(parentActor, touchEventHandle);
+
+ tp = GenerateDoubleTouch(PointState::MOTION, Vector2(10.0f, 20.0f), PointState::MOTION, Vector2(30.0f, 20.0f), 200);
+ touchEventImpl = new Internal::TouchEvent(200);
+ touchEventImpl->AddPoint(tp.GetPoint(0));
+ touchEventImpl->AddPoint(tp.GetPoint(1));
+ touchEventImpl->SetRenderTask(task);
+ touchEventHandle = Dali::TouchEvent(touchEventImpl.Get());
+ parentDetector.FeedTouch(parentActor, touchEventHandle);
+
+ tp = GenerateDoubleTouch(PointState::MOTION, Vector2(10.0f, 20.0f), PointState::MOTION, Vector2(30.0f, 20.0f), 250);
+ touchEventImpl = new Internal::TouchEvent(250);
+ touchEventImpl->AddPoint(tp.GetPoint(0));
+ touchEventImpl->AddPoint(tp.GetPoint(1));
+ touchEventImpl->SetRenderTask(task);
+ touchEventHandle = Dali::TouchEvent(touchEventImpl.Get());
+ parentDetector.FeedTouch(parentActor, touchEventHandle);
+
+ tp = GenerateDoubleTouch(PointState::MOTION, Vector2(6.0f, 6.0f), PointState::MOTION, Vector2(18.0f, 18.0f), 300);
+ touchEventImpl = new Internal::TouchEvent(300);
+ touchEventImpl->AddPoint(tp.GetPoint(0));
+ touchEventImpl->AddPoint(tp.GetPoint(1));
+ touchEventImpl->SetRenderTask(task);
+ touchEventHandle = Dali::TouchEvent(touchEventImpl.Get());
+ parentDetector.FeedTouch(parentActor, touchEventHandle);
+
+ tp = GenerateDoubleTouch(PointState::UP, Vector2(10.0f, 8.0f), PointState::UP, Vector2(14.0f, 16.0f), 350);
+ touchEventImpl = new Internal::TouchEvent(350);
+ touchEventImpl->AddPoint(tp.GetPoint(0));
+ touchEventImpl->AddPoint(tp.GetPoint(1));
+ touchEventImpl->SetRenderTask(task);
+ touchEventHandle = Dali::TouchEvent(touchEventImpl.Get());
+ parentDetector.FeedTouch(parentActor, touchEventHandle);
+
+
+ DALI_TEST_EQUALS(true, pData.functorCalled, TEST_LOCATION);
+ pData.Reset();
+
+ END_TEST;
+}
#include <dali-test-suite-utils.h>
#include <dali/devel-api/actors/actor-devel.h>
#include <dali/integration-api/events/touch-event-integ.h>
+#include <dali/integration-api/events/touch-integ.h>
#include <dali/integration-api/render-task-list-integ.h>
+#include <dali/internal/event/events/touch-event-impl.h>
+#include <dali/internal/event/render-tasks/render-task-impl.h>
#include <dali/public-api/dali-core.h>
#include <stdlib.h>
#include <test-touch-event-utils.h>
END_TEST;
}
+
+int UtcDaliTapGestureFeedTouch(void)
+{
+ TestApplication application;
+ Integration::Scene scene = application.GetScene();
+ RenderTaskList taskList = scene.GetRenderTaskList();
+ Dali::RenderTask task = taskList.GetTask(0);
+
+ Actor parentActor = Actor::New();
+ parentActor.SetProperty(Actor::Property::SIZE, Vector2(100.0f, 100.0f));
+ parentActor.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
+
+ Actor childActor = Actor::New();
+ childActor.SetProperty(Actor::Property::SIZE, Vector2(100.0f, 100.0f));
+ childActor.SetProperty(Actor::Property::ANCHOR_POINT, AnchorPoint::TOP_LEFT);
+
+ parentActor.Add(childActor);
+ application.GetScene().Add(parentActor);
+
+ // Render and notify
+ application.SendNotification();
+ application.Render();
+
+ SignalData pData;
+ GestureReceivedFunctor pFunctor(pData);
+
+ TapGestureDetector parentDetector = TapGestureDetector::New();
+ parentDetector.DetectedSignal().Connect(&application, pFunctor);
+
+ Integration::TouchEvent tp = GenerateSingleTouch(PointState::DOWN, Vector2(50.0f, 50.0f), 1, 100);
+ Internal::TouchEventPtr touchEventImpl(new Internal::TouchEvent(100));
+ touchEventImpl->AddPoint(tp.GetPoint(0));
+ touchEventImpl->SetRenderTask(task);
+ Dali::TouchEvent touchEventHandle(touchEventImpl.Get());
+ parentDetector.FeedTouch(parentActor, touchEventHandle);
+
+ tp = GenerateSingleTouch(PointState::UP, Vector2(50.0f, 50.0f), 1, 150);
+ touchEventImpl = new Internal::TouchEvent(150);
+ touchEventImpl->AddPoint(tp.GetPoint(0));
+ touchEventImpl->SetRenderTask(task);
+ touchEventHandle = Dali::TouchEvent(touchEventImpl.Get());
+ parentDetector.FeedTouch(parentActor, touchEventHandle);
+
+ DALI_TEST_EQUALS(true, pData.functorCalled, TEST_LOCATION);
+ pData.Reset();
+
+ END_TEST;
+}
/*
- * Copyright (c) 2023 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2024 Samsung Electronics Co., Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
#include <dali-test-suite-utils.h>
#include <dali/devel-api/rendering/texture-devel.h>
+#include <dali/integration-api/pixel-data-integ.h>
#include <dali/integration-api/texture-integ.h>
#include <dali/public-api/dali-core.h>
#include <test-native-image.h>
END_TEST;
}
+int UtcDaliTextureUpload09(void)
+{
+ TestApplication application;
+
+ //Create the texture
+ uint32_t width(64u);
+ uint32_t height(64u);
+ Texture texture = CreateTexture(TextureType::TEXTURE_2D, Pixel::RGBA8888, width, height);
+
+ application.GetGlAbstraction().EnableTextureCallTrace(true);
+
+ application.SendNotification();
+ application.Render();
+
+ TraceCallStack& callStack = application.GetGlAbstraction().GetTextureTrace();
+
+ //Upload data to the texture
+ callStack.Reset();
+
+ uint32_t bufferSize(width * height * 4u);
+ uint8_t* buffer = reinterpret_cast<uint8_t*>(malloc(bufferSize));
+ buffer[0] = 'a';
+
+ PixelData pixelData = Dali::Integration::NewPixelDataWithReleaseAfterUpload(buffer, bufferSize, width, height, 0u, Pixel::RGBA8888, PixelData::FREE);
+ DALI_TEST_CHECK(pixelData);
+
+ Dali::Integration::PixelDataBuffer pixelDataBuffer = Dali::Integration::GetPixelDataBuffer(pixelData);
+
+ DALI_TEST_EQUALS(pixelDataBuffer.bufferSize, bufferSize, TEST_LOCATION);
+ DALI_TEST_EQUALS(pixelDataBuffer.buffer[0], static_cast<uint8_t>('a'), TEST_LOCATION);
+
+ texture.Upload(pixelData);
+
+ application.SendNotification();
+ application.Render();
+
+ //TexImage2D should be called to upload the data
+ {
+ std::stringstream out;
+ out << GL_TEXTURE_2D << ", " << 0u << ", " << width << ", " << height;
+ DALI_TEST_CHECK(callStack.FindMethodAndParams("TexImage2D", out.str().c_str()));
+ }
+
+ // Check whether the buffer become nullptr after texture uploaded.
+ pixelDataBuffer = Dali::Integration::GetPixelDataBuffer(pixelData);
+
+ DALI_TEST_CHECK(pixelDataBuffer.buffer == nullptr);
+
+ END_TEST;
+}
+
int UtcDaliTextureUploadSubPixelData01(void)
{
TestApplication application;
/*
- * Copyright (c) 2023 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2024 Samsung Electronics Co., Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
namespace Dali::Integration
{
-PixelDataBuffer ReleasePixelDataBuffer(Dali::PixelData& pixelData)
+void ReleasePixelDataBuffer(Dali::PixelData pixelData)
{
- Internal::PixelData& pixelDataImpl = GetImplementation(pixelData);
- PixelDataBuffer pixelDataBuffer = pixelDataImpl.ReleasePixelDataBuffer();
- pixelData.Reset();
- return pixelDataBuffer;
+ Internal::PixelData& pixelDataImpl = GetImplementation(pixelData);
+ pixelDataImpl.ReleasePixelDataBuffer();
}
PixelDataBuffer GetPixelDataBuffer(const Dali::PixelData& pixelData)
PixelDataBuffer pixelDataBuffer = pixelDataImpl.GetPixelDataBuffer();
return pixelDataBuffer;
}
+
+Dali::PixelData NewPixelDataWithReleaseAfterUpload(uint8_t* buffer,
+ uint32_t bufferSize,
+ uint32_t width,
+ uint32_t height,
+ uint32_t stride,
+ Pixel::Format pixelFormat,
+ PixelData::ReleaseFunction releaseFunction)
+{
+ IntrusivePtr<Internal::PixelData> internal = Internal::PixelData::New(buffer, bufferSize, width, height, stride, pixelFormat, releaseFunction, true);
+ return PixelData(internal.Get());
+}
+
+bool IsPixelDataReleaseAfterUpload(const Dali::PixelData& pixelData)
+{
+ const Internal::PixelData& pixelDataImpl = GetImplementation(pixelData);
+ return pixelDataImpl.IsPixelDataReleaseAfterUpload();
+}
} // namespace Dali::Integration
#define DALI_PIXEL_DATA_INTEG_H
/*
- * Copyright (c) 2023 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2024 Samsung Electronics Co., Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
*/
struct PixelDataBuffer
{
- uint8_t* buffer;
- uint32_t bufferSize;
- Dali::PixelData::ReleaseFunction releaseFunction;
+ uint8_t* buffer;
+ uint32_t bufferSize;
+ uint32_t width;
+ uint32_t height;
+ uint32_t stride;
- PixelDataBuffer(uint8_t* buffer,
- uint32_t bufferSize,
- Dali::PixelData::ReleaseFunction releaseFunction)
+ PixelDataBuffer(uint8_t* buffer,
+ uint32_t bufferSize,
+ uint32_t width,
+ uint32_t height,
+ uint32_t stride = 0)
: buffer(buffer),
bufferSize(bufferSize),
- releaseFunction(releaseFunction)
+ width(width),
+ height(height),
+ stride(stride)
{
}
};
/**
- * Get the buffer from a pixel data object, zero it in the pixel data object
- * and release the handle.
- * @param[in,out] pixelData The pixel data object to take the buffer from
- * @return the buffer and the data release mechanism
+ * Release the buffer from a pixel data object, zero it in the pixel data object.
+ * @param[in] pixelData The pixel data object to take the buffer from
*/
-DALI_CORE_API PixelDataBuffer ReleasePixelDataBuffer(Dali::PixelData& pixelData);
+DALI_CORE_API void ReleasePixelDataBuffer(Dali::PixelData pixelData);
/**
* Get the buffer from a pixel data object.
*/
DALI_CORE_API PixelDataBuffer GetPixelDataBuffer(const Dali::PixelData& pixelData);
+/**
+ * Creates a PixelData object which will release the buffer automatically after upload to texture.
+ * @return The pixel data object.
+ */
+DALI_CORE_API Dali::PixelData NewPixelDataWithReleaseAfterUpload(uint8_t* buffer,
+ uint32_t bufferSize,
+ uint32_t width,
+ uint32_t height,
+ uint32_t stride,
+ Pixel::Format pixelFormat,
+ PixelData::ReleaseFunction releaseFunction);
+
+/**
+ * Get whether we need to release pixel data after texture upload or not.
+ * @note This function can be called from another thread. Be careful about thread safety.
+ * @param[in] pixelData The pixel data object to get the release policy.
+ * @return True if we need to release pixel data after texture upload. False otherwise.
+ */
+DALI_CORE_API bool IsPixelDataReleaseAfterUpload(const Dali::PixelData& pixelData);
+
} // namespace Dali::Integration
#endif // DALI_PIXEL_DATA_INTEG_H
worldPosition -= cameraPosition;
Vector3 actorSize = node.GetSize(bufferIndex) * node.GetWorldScale(bufferIndex);
- auto sceneSize = scene.GetCurrentSurfaceRect(); // Use the update object's size
+ const auto& sceneSize = scene.GetCurrentSurfaceRect(); // Use the update object's size
Vector2 halfSceneSize(sceneSize.width * 0.5f, sceneSize.height * 0.5f); // World position origin is center of scene
Vector3 halfActorSize(actorSize * 0.5f);
Vector3 anchorPointOffSet = halfActorSize - actorSize * actor.GetAnchorPointForPosition();
const auto& node = actor.GetNode();
Scene& scene = actor.GetScene();
- auto worldMatrix = node.GetWorldMatrix(bufferIndex);
+ const auto& worldMatrix = node.GetWorldMatrix(bufferIndex);
const auto& renderTaskList = scene.GetRenderTaskList();
ConvertLocalToScreenRenderTaskList(renderTaskList, actor, worldMatrix, node.GetSize(bufferIndex) * (actor.GetAnchorPointForPosition() - Vector3(0.5f, 0.5f, 0.5f)), result.x, result.y);
}
const auto& node = actor.GetNode();
Scene& scene = actor.GetScene();
- auto worldMatrix = node.GetWorldMatrix(bufferIndex);
+ const auto& worldMatrix = node.GetWorldMatrix(bufferIndex);
const auto& renderTaskList = scene.GetRenderTaskList();
ConvertLocalToScreenExtentRenderTaskList(renderTaskList, actor, worldMatrix, node.GetSize(bufferIndex), result);
}
}
// To cover swapping components, previous and current components should be compared.
- if(mObject->GetPropertyType(mObjectPropertyIndex) == Property::VECTOR3)
+ if(mObject->GetPropertyType(mObjectPropertyIndex) == Property::VECTOR3 ||
+ mObject->GetPropertyType(mObjectPropertyIndex) == Property::ROTATION)
{
mCompare = true;
for(int i = 0; i < 3; ++i)
#include <dali/internal/event/common/thread-local-storage.h>
#include <dali/internal/event/events/actor-gesture-data.h>
#include <dali/internal/event/events/gesture-event-processor.h>
+#include <dali/internal/event/events/touch-event-impl.h>
+#include <dali/internal/event/render-tasks/render-task-impl.h>
namespace Dali
{
return actor;
}
+bool GestureDetector::FeedTouch(Dali::Actor& actor, Dali::TouchEvent& touch)
+{
+ bool ret = false;
+ if(touch.GetPointCount() > 0)
+ {
+ const PointState::Type state = touch.GetState(0);
+ Dali::Internal::Actor& actorImpl(GetImplementation(actor));
+ if(state == PointState::DOWN)
+ {
+ Attach(actorImpl);
+ }
+
+ Integration::TouchEvent touchEvent(touch.GetTime());
+ for(std::size_t i = 0; i< touch.GetPointCount(); i++)
+ {
+ Integration::Point point;
+ point.SetState(touch.GetState(i));
+ point.SetDeviceId(touch.GetDeviceId(i));
+ point.SetScreenPosition(touch.GetScreenPosition(i));
+ point.SetRadius(touch.GetRadius(i));
+ point.SetPressure(touch.GetPressure(i));
+ point.SetAngle(touch.GetAngle(i));
+ point.SetDeviceClass(touch.GetDeviceClass(i));
+ point.SetDeviceSubclass(touch.GetDeviceSubclass(i));
+ point.SetMouseButton(touch.GetMouseButton(i));
+ point.SetHitActor(touch.GetHitActor(i));
+ point.SetLocalPosition(touch.GetLocalPosition(i));
+ touchEvent.points.push_back(point);
+ }
+
+ Dali::Internal::TouchEvent& touchEventImpl(GetImplementation(touch));
+ mGestureEventProcessor.ProcessTouchEvent(this, actorImpl, GetImplementation(touchEventImpl.GetRenderTaskPtr()), actorImpl.GetScene(), touchEvent);
+
+ if(state == PointState::FINISHED || state == PointState::INTERRUPTED || state == PointState::LEAVE)
+ {
+ Detach(actorImpl);
+ }
+ ret = true;
+ }
+ return ret;
+}
+
bool GestureDetector::IsAttached(Actor& actor) const
{
return (find(mPendingAttachActors.begin(), mPendingAttachActors.end(), &actor) != mPendingAttachActors.end()) ||
Dali::Actor GetAttachedActor(size_t index) const;
/**
+ * @copydoc Dali::GestureDetector::FeedTouch()
+ */
+ bool FeedTouch(Dali::Actor& actor, Dali::TouchEvent& touch);
+
+ /**
* Returns a const reference to the container of attached actor pointers.
* @return A const reference to the attached internal actors.
*/
mRotationGestureProcessor.ProcessTouch(scene, event);
}
+void GestureEventProcessor::ProcessTouchEvent(GestureDetector* gestureDetector, Actor& actor, Dali::Internal::RenderTask& renderTask, Scene& scene, const Integration::TouchEvent& event)
+{
+ switch(gestureDetector->GetType())
+ {
+ case GestureType::LONG_PRESS:
+ {
+ mLongPressGestureProcessor.ProcessTouch(actor, renderTask, scene, event);
+ break;
+ }
+
+ case GestureType::PAN:
+ {
+ mPanGestureProcessor.ProcessTouch(actor, renderTask, scene, event);
+ break;
+ }
+
+ case GestureType::PINCH:
+ {
+ mPinchGestureProcessor.ProcessTouch(actor, renderTask, scene, event);
+ break;
+ }
+
+ case GestureType::TAP:
+ {
+ mTapGestureProcessor.ProcessTouch(actor, renderTask, scene, event);
+ break;
+ }
+
+ case GestureType::ROTATION:
+ {
+ mRotationGestureProcessor.ProcessTouch(actor, renderTask, scene, event);
+ break;
+ }
+ }
+}
+
void GestureEventProcessor::AddGestureDetector(GestureDetector* gestureDetector, Scene& scene)
{
switch(gestureDetector->GetType())
*/
void ProcessTouchEvent(Scene& scene, const Integration::TouchEvent& event);
+ /**
+ * This function is called by gesture detector whenever a touch event occurs
+ * @param[in] gestureDetector The gesture detector
+ * @param[in] actor The actor
+ * @param[in] renderTask The renderTask
+ * @param[in] scene The scene
+ * @param[in] event The event that has occurred
+ */
+ void ProcessTouchEvent(GestureDetector* gestureDetector, Actor& actor, Dali::Internal::RenderTask& renderTask, Scene& scene, const Integration::TouchEvent& event);
+
public: // To be called by gesture detectors
/**
* This method adds the specified gesture detector to the relevant gesture processor.
// INTERNAL INCLUDES
#include <dali/integration-api/events/event.h>
#include <dali/internal/event/events/gesture-impl.h>
+#include <dali/internal/event/render-tasks/render-task-impl.h>
namespace Dali
{
*/
GestureSourceData sourceData;
+ /**
+ * The render task used to generate this touch event.
+ */
+ RenderTaskPtr renderTask;
+
+
protected: // Constructors only to be used by derived structures.
/**
* This constructor is only used by derived classes.
}
}
+void GestureProcessor::ProcessTouch(Actor& actor, Dali::Internal::RenderTask& renderTask, Scene& scene, const Integration::TouchEvent& event)
+{
+ if(mGestureRecognizer)
+ {
+ if(!event.points.empty())
+ {
+ mPoint = event.points[0];
+ mEventTime = event.time;
+ }
+ mGestureRecognizer->SendEvent(actor, renderTask, scene, event);
+ }
+}
+
void GestureProcessor::GetGesturedActor(Actor*& actor, GestureDetectorContainer& gestureDetectors)
{
while(actor)
}
}
+void GestureProcessor::ProcessAndEmitActor(HitTestAlgorithm::Results& hitTestResults)
+{
+ if(hitTestResults.actor)
+ {
+ Actor* hitTestActor(&GetImplementation(hitTestResults.actor));
+ Actor* actor(hitTestActor);
+ GestureDetectorContainer gestureDetectors;
+ GetGesturedActor(actor, gestureDetectors);
+
+ if(actor && actor->IsVisible() && !gestureDetectors.empty() && actor == hitTestActor)
+ {
+ EmitGestureSignal(actor, gestureDetectors, hitTestResults.actorCoordinates);
+ }
+ }
+}
+
bool GestureProcessor::HitTest(Scene& scene, Vector2 screenCoordinates, HitTestAlgorithm::Results& hitTestResults)
{
GestureHitTestCheck hitCheck(mType);
void ProcessTouch(Scene& scene, const Integration::TouchEvent& event);
/**
+ * Process the touch event in the attached recognizer
+ * @param[in] actor The actor which gesture want to recognize.
+ * @param[in] renderTask RenderTask.
+ * @param[in] scene Scene.
+ * @param[in] event Touch event to process
+ */
+ void ProcessTouch(Actor& actor, Dali::Internal::RenderTask& renderTask, Scene& scene, const Integration::TouchEvent& event);
+
+ /**
* Returns whether any GestureDetector requires a Core::Update
* @return true if update required
*/
void ProcessAndEmit(HitTestAlgorithm::Results& hitTestResults);
/**
+ * Calls the emission method in the deriving class for actor
+ *
+ * @param[in] hitTestResults The Hit Test Results.
+ *
+ * @note Uses the CheckGestureDetector() to check if the gesture matches the criteria of the given gesture detector
+ * and EmitGestureSignal() to emit the signal.
+ * @pre Hit Testing should already be done.
+ */
+ void ProcessAndEmitActor(HitTestAlgorithm::Results& hitTestResults);
+
+ /**
* Hit test the screen coordinates, and place the results in hitTestResults.
* @param[in] scene Scene.
* @param[in] screenCoordinates The screen coordinates to test.
// EXTERNAL INCLUDES
#include <dali/integration-api/events/touch-event-integ.h>
+#include <dali/internal/event/events/actor-observer.h>
#include <dali/internal/event/events/gesture-event.h>
+#include <dali/internal/event/render-tasks/render-task-impl.h>
#include <dali/public-api/common/vector-wrapper.h>
#include <dali/public-api/events/gesture.h>
#include <dali/public-api/math/vector2.h>
class RecognizerObserver
{
public:
- virtual void Process(Scene& scene, const T& event) = 0;
+ virtual void Process(Scene& scene, const T& event, Actor* actor = nullptr) = 0;
virtual ~RecognizerObserver() = default;
;
SendEvent(event);
}
+ /**
+ * Called when we get a touch event.
+ * @param[in] actor The actor the touch event has occurred on
+ * @param[in] renderTask The renderTask the touch event has occurred on
+ * @param[in] scene The scene the touch event has occurred on
+ * @param[in] event The latest touch event
+ */
+ void SendEvent(Actor& actor, Dali::Internal::RenderTask& renderTask, Scene& scene, const Integration::TouchEvent& event)
+ {
+ mActor.SetActor(&actor);
+ mRenderTask = &renderTask;
+ SendEvent(scene, event);
+ }
+
protected:
/**
* Protected Constructor. Should only be able to create derived class objects.
mType(detectorType),
mScene(nullptr),
mSourceType(GestureSourceType::INVALID),
- mSourceData(GestureSourceData::INVALID)
+ mSourceData(GestureSourceData::INVALID),
+ mActor(),
+ mRenderTask()
{
}
~GestureRecognizer() override = default;
protected:
- Vector2 mScreenSize;
- GestureType::Value mType;
- Scene* mScene;
- GestureSourceType mSourceType; /// < Gesture input source type.
- GestureSourceData mSourceData; /// < Gesture input source data.
+ Vector2 mScreenSize;
+ GestureType::Value mType;
+ Scene* mScene;
+ GestureSourceType mSourceType; /// < Gesture input source type.
+ GestureSourceData mSourceData; /// < Gesture input source data.
+ ActorObserver mActor; /// < The actor used to generate this touch event.
+ RenderTaskPtr mRenderTask; /// < The render task used to generate this touch event.
};
using GestureRecognizerPtr = IntrusivePtr<GestureRecognizer>;
for(auto&& currentPoint : event.points)
{
HitTestAlgorithm::Results hitTestResults;
+ hitTestResults.eventTime = event.time;
ActorHoverableCheck actorHoverableCheck;
HitTestAlgorithm::HitTest(mScene.GetSize(), mScene.GetRenderTaskList(), mScene.GetLayerList(), currentPoint.GetScreenPosition(), hitTestResults, actorHoverableCheck, isGeometry);
LongPressGestureProcessor::~LongPressGestureProcessor() = default;
-void LongPressGestureProcessor::Process(Scene& scene, const LongPressGestureEvent& longPressEvent)
+void LongPressGestureProcessor::Process(Scene& scene, const LongPressGestureEvent& longPressEvent, Actor* actor)
{
DALI_TRACE_SCOPE(gTraceFilter, "DALI_PROCESS_LONG_PRESS_GESTURE");
switch(longPressEvent.state)
ResetActor();
HitTestAlgorithm::Results hitTestResults;
- if(HitTest(scene, longPressEvent.point, hitTestResults))
+ if(actor)
+ {
+ SetActor(actor);
+ }
+ else if(HitTest(scene, longPressEvent.point, hitTestResults))
{
SetActor(&GetImplementation(hitTestResults.actor));
}
if(currentGesturedActor)
{
HitTestAlgorithm::Results hitTestResults;
- HitTest(scene, longPressEvent.point, hitTestResults);
+ if(actor)
+ {
+ hitTestResults.actor = Dali::Actor(actor);
+ hitTestResults.renderTask = longPressEvent.renderTask;
+
+ Vector2 actorCoords;
+ currentGesturedActor->ScreenToLocal(*hitTestResults.renderTask.Get(), actorCoords.x, actorCoords.y, longPressEvent.point.x, longPressEvent.point.y);
+ hitTestResults.actorCoordinates = actorCoords;
+ }
+ else
+ {
+ HitTest(scene, longPressEvent.point, hitTestResults);
+ }
if(hitTestResults.actor && (currentGesturedActor == &GetImplementation(hitTestResults.actor)))
{
// Set mCurrentLongPressEvent to use inside overridden methods called from ProcessAndEmit()
mCurrentLongPressEvent = &longPressEvent;
- ProcessAndEmit(hitTestResults);
+ if(actor)
+ {
+ ProcessAndEmitActor(hitTestResults);
+ }
+ else
+ {
+ ProcessAndEmit(hitTestResults);
+ }
mCurrentLongPressEvent = nullptr;
}
else
* This method is called whenever a long press gesture event occurs.
* @param[in] scene The scene the long press gesture event occurs in.
* @param[in] longPressEvent The event that has occurred.
+ * @param[in] actor The actor where the event occurred. If this is null, the actor is found through hittest.
*/
- void Process(Scene& scene, const LongPressGestureEvent& longPressEvent) override;
+ void Process(Scene& scene, const LongPressGestureEvent& longPressEvent, Actor* actor = nullptr) override;
/**
* Adds a gesture detector to this gesture processor.
}
longPress.sourceType = mSourceType;
longPress.sourceData = mSourceData;
+ longPress.renderTask = mRenderTask;
if(mScene)
{
// Create another handle so the recognizer cannot be destroyed during process function
GestureRecognizerPtr recognizerHandle = this;
- mObserver.Process(*mScene, longPress);
+ mObserver.Process(*mScene, longPress, mActor.GetActor());
}
}
}
mSceneObject = nullptr; // mSceneObject is owned and destroyed by update manager (there is only one of these for now)
}
-void PanGestureProcessor::Process(Scene& scene, const PanGestureEvent& panEvent)
+void PanGestureProcessor::Process(Scene& scene, const PanGestureEvent& panEvent, Actor* actor)
{
#if defined(DEBUG_ENABLED)
DALI_LOG_TRACE_METHOD(gLogFilter);
ResetActor();
HitTestAlgorithm::Results hitTestResults;
- if(HitTest(scene, panEvent.currentPosition, hitTestResults))
+ if(actor)
+ {
+ SetActor(actor);
+ mPossiblePanPosition = panEvent.currentPosition;
+ }
+ else if(HitTest(scene, panEvent.currentPosition, hitTestResults))
{
SetActor(&GetImplementation(hitTestResults.actor));
mPossiblePanPosition = panEvent.currentPosition;
// it can be told when the gesture ends as well.
HitTestAlgorithm::Results hitTestResults;
- HitTest(scene, panEvent.previousPosition, hitTestResults); // Hit Test previous position
+ if(actor)
+ {
+ hitTestResults.actor = Dali::Actor(actor);
+ hitTestResults.renderTask = panEvent.renderTask;
+
+ Vector2 actorCoords;
+ actor->ScreenToLocal(*hitTestResults.renderTask.Get(), actorCoords.x, actorCoords.y, panEvent.currentPosition.x, panEvent.currentPosition.y);
+ hitTestResults.actorCoordinates = actorCoords;
+ }
+ else
+ {
+ HitTest(scene, panEvent.previousPosition, hitTestResults); // Hit Test previous position
+ }
if(hitTestResults.actor)
{
// Set mCurrentPanEvent to use inside overridden methods called in ProcessAndEmit()
mCurrentPanEvent = &panEvent;
- ProcessAndEmit(hitTestResults);
+ if(actor)
+ {
+ ProcessAndEmitActor(hitTestResults);
+ }
+ else
+ {
+ ProcessAndEmit(hitTestResults);
+ }
mCurrentPanEvent = nullptr;
}
else
* This method is called whenever a pan gesture event occurs.
* @param[in] scene The scene the pan gesture event occurs in.
* @param[in] panEvent The event that has occurred.
+ * @param[in] actor The actor where the event occurred. If this is null, the actor is found through hittest.
*/
- void Process(Scene& scene, const PanGestureEvent& panEvent) override;
+ void Process(Scene& scene, const PanGestureEvent& panEvent, Actor* actor = nullptr) override;
/**
* Adds a gesture detector to this gesture processor.
gesture.time = currentEvent.time;
gesture.sourceType = mSourceType;
gesture.sourceData = mSourceData;
+ gesture.renderTask = mRenderTask;
if(mScene)
{
// Create another handle so the recognizer cannot be destroyed during process function
GestureRecognizerPtr recognizerHandle = this;
- mObserver.Process(*mScene, gesture);
+ mObserver.Process(*mScene, gesture, mActor.GetActor());
}
}
}
}
-void PinchGestureProcessor::Process(Scene& scene, const PinchGestureEvent& pinchEvent)
+void PinchGestureProcessor::Process(Scene& scene, const PinchGestureEvent& pinchEvent, Actor* actor)
{
DALI_TRACE_SCOPE(gTraceFilter, "DALI_PROCESS_PINCH_GESTURE");
switch(pinchEvent.state)
ResetActor();
HitTestAlgorithm::Results hitTestResults;
- if(HitTest(scene, pinchEvent.centerPoint, hitTestResults))
+ if(actor)
+ {
+ hitTestResults.actor = Dali::Actor(actor);
+ hitTestResults.renderTask = pinchEvent.renderTask;
+
+ // Record the current render-task for Screen->Actor coordinate conversions
+ mCurrentRenderTask = hitTestResults.renderTask;
+
+ Vector2 actorCoords;
+ actor->ScreenToLocal(*mCurrentRenderTask.Get(), actorCoords.x, actorCoords.y, pinchEvent.centerPoint.x, pinchEvent.centerPoint.y);
+ hitTestResults.actorCoordinates = actorCoords;
+
+ // Set mCurrentPinchEvent to use inside overridden methods called from ProcessAndEmit()
+ mCurrentPinchEvent = &pinchEvent;
+ ProcessAndEmitActor(hitTestResults);
+ mCurrentPinchEvent = nullptr;
+ }
+ else if(HitTest(scene, pinchEvent.centerPoint, hitTestResults))
{
// Record the current render-task for Screen->Actor coordinate conversions
mCurrentRenderTask = hitTestResults.renderTask;
* This method is called whenever a pinch gesture event occurs.
* @param[in] scene The scene the pinch gesture event occurs in.
* @param[in] pinchEvent The event that has occurred.
+ * @param[in] actor The actor where the event occurred. If this is null, the actor is found through hittest.
*/
- void Process(Scene& scene, const PinchGestureEvent& pinchEvent) override;
+ void Process(Scene& scene, const PinchGestureEvent& pinchEvent, Actor* actor = nullptr) override;
/**
* Adds a gesture detector to this gesture processor.
gesture.time = currentEvent.time;
gesture.sourceType = mSourceType;
gesture.sourceData = mSourceData;
+ gesture.renderTask = mRenderTask;
if(mScene)
{
// Create another handle so the recognizer cannot be destroyed during process function
GestureRecognizerPtr recognizerHandle = this;
- mObserver.Process(*mScene, gesture);
+ mObserver.Process(*mScene, gesture, mActor.GetActor());
}
}
{
}
-void RotationGestureProcessor::Process(Scene& scene, const RotationGestureEvent& rotationEvent)
+void RotationGestureProcessor::Process(Scene& scene, const RotationGestureEvent& rotationEvent, Actor* actor)
{
DALI_TRACE_SCOPE(gTraceFilter, "DALI_PROCESS_ROTATION_GESTURE");
switch(rotationEvent.state)
ResetActor();
HitTestAlgorithm::Results hitTestResults;
- if(HitTest(scene, rotationEvent.centerPoint, hitTestResults))
+ if(actor)
+ {
+ hitTestResults.actor = Dali::Actor(actor);
+ hitTestResults.renderTask = rotationEvent.renderTask;
+
+ // Record the current render-task for Screen->Actor coordinate conversions
+ mCurrentRenderTask = hitTestResults.renderTask;
+
+ Vector2 actorCoords;
+ actor->ScreenToLocal(*mCurrentRenderTask.Get(), actorCoords.x, actorCoords.y, rotationEvent.centerPoint.x, rotationEvent.centerPoint.y);
+ hitTestResults.actorCoordinates = actorCoords;
+
+ // Set mCurrentRotationEvent to use inside overridden methods called from ProcessAndEmit()
+ mCurrentRotationEvent = &rotationEvent;
+ ProcessAndEmitActor(hitTestResults);
+ mCurrentRotationEvent = nullptr;
+
+ }
+ else if(HitTest(scene, rotationEvent.centerPoint, hitTestResults))
{
// Record the current render-task for Screen->Actor coordinate conversions
mCurrentRenderTask = hitTestResults.renderTask;
* This method is called whenever a rotation gesture event occurs.
* @param[in] scene The scene the rotation gesture event occurs in.
* @param[in] rotationEvent The event that has occurred.
+ * @param[in] actor The actor where the event occurred. If this is null, the actor is found through hittest.
*/
- void Process(Scene& scene, const RotationGestureEvent& rotationEvent) override;
+ void Process(Scene& scene, const RotationGestureEvent& rotationEvent, Actor* actor = nullptr) override;
/**
* Adds a gesture detector to this gesture processor.
gesture.time = currentEvent.time;
gesture.sourceType = mSourceType;
gesture.sourceData = mSourceData;
+ gesture.renderTask = mRenderTask;
if(mScene)
{
// Create another handle so the recognizer cannot be destroyed during process function
GestureRecognizerPtr recognizerHandle = this;
- mObserver.Process(*mScene, gesture);
+ mObserver.Process(*mScene, gesture, mActor.GetActor());
}
}
TapGestureProcessor::~TapGestureProcessor() = default;
-void TapGestureProcessor::Process(Scene& scene, const TapGestureEvent& tapEvent)
+void TapGestureProcessor::Process(Scene& scene, const TapGestureEvent& tapEvent, Actor* actor)
{
DALI_TRACE_SCOPE(gTraceFilter, "DALI_PROCESS_TAP_GESTURE");
switch(tapEvent.state)
{
// Do a hit test and if an actor has been hit then save to see if tap event is still valid on a tap( same actor being hit )
HitTestAlgorithm::Results hitTestResults;
- if(HitTest(scene, tapEvent.point, hitTestResults))
+ if(actor)
+ {
+ SetActor(actor);
+ mCurrentTapActor.SetActor(GetCurrentGesturedActor());
+
+ // Indicate that we've processed a touch down. Bool should be sufficient as a change in actor will result in a cancellation
+ mPossibleProcessed = true;
+ }
+ else if(HitTest(scene, tapEvent.point, hitTestResults))
{
SetActor(&GetImplementation(hitTestResults.actor));
mCurrentTapActor.SetActor(GetCurrentGesturedActor());
{
// Ensure that we're processing a hit on the current actor and that we've already processed a touch down
HitTestAlgorithm::Results hitTestResults;
- if(GetCurrentGesturedActor() && HitTest(scene, tapEvent.point, hitTestResults) && mPossibleProcessed)
+ if(GetCurrentGesturedActor())
{
- // Check that this actor is still the one that was used for the last touch down ?
- if(mCurrentTapActor.GetActor() == &GetImplementation(hitTestResults.actor))
+ if(actor)
+ {
+ hitTestResults.actor = Dali::Actor(actor);
+ hitTestResults.renderTask = tapEvent.renderTask;
+ // Check that this actor is still the one that was used for the last touch down ?
+ if(mCurrentTapActor.GetActor() == &GetImplementation(hitTestResults.actor))
+ {
+ mCurrentTapEvent = &tapEvent;
+ ProcessAndEmitActor(hitTestResults);
+ }
+ mCurrentTapEvent = nullptr;
+ mPossibleProcessed = false;
+ }
+ else if(HitTest(scene, tapEvent.point, hitTestResults) && mPossibleProcessed)
{
- mCurrentTapEvent = &tapEvent;
- ProcessAndEmit(hitTestResults);
+ // Check that this actor is still the one that was used for the last touch down ?
+ if(mCurrentTapActor.GetActor() == &GetImplementation(hitTestResults.actor))
+ {
+ mCurrentTapEvent = &tapEvent;
+ ProcessAndEmit(hitTestResults);
+ }
+ mCurrentTapEvent = nullptr;
+ mPossibleProcessed = false;
}
- mCurrentTapEvent = nullptr;
- mPossibleProcessed = false;
}
break;
}
* This method is called whenever a tap gesture event occurs.
* @param[in] scene The scene the tap gesture event occurs in.
* @param[in] tapEvent The event that has occurred.
+ * @param[in] actor The actor where the event occurred. If this is null, the actor is found through hittest.
*/
- void Process(Scene& scene, const TapGestureEvent& event) override;
+ void Process(Scene& scene, const TapGestureEvent& event, Actor* actor = nullptr) override;
/**
* Adds a gesture detector to this gesture processor.
{
event.sourceType = mSourceType;
event.sourceData = mSourceData;
+ event.renderTask = mRenderTask;
if(mScene)
{
// Create another handle so the recognizer cannot be destroyed during process function
GestureRecognizerPtr recognizerHandle = this;
- mObserver.Process(*mScene, event);
+ mObserver.Process(*mScene, event, mActor.GetActor());
}
}
return mRenderTask;
}
+ Dali::RenderTask& GetRenderTaskPtr()
+ {
+ return mRenderTask;
+ }
+
// Setters
/**
// geometry
// child -> below
-Dali::Actor EmitGeoInterceptTouchSignals(std::list<Dali::Internal::Actor*>& actorLists, std::list<Dali::Internal::Actor*>& interceptActorList, const Dali::TouchEvent& touchEvent)
+Dali::Actor EmitGeoInterceptTouchSignals(std::list<Dali::Internal::Actor*>& actorLists, std::list<Dali::Internal::Actor*>& interceptActorList, const Dali::TouchEvent& touchEvent, ActorObserver& lastConsumedActor)
{
interceptActorList.clear();
Dali::Actor interceptedActor;
for(auto&& actor : actorLists)
{
+ // If there is a consumed actor, the intercept is sent only up to the moment before the consumed actor.
+ if(lastConsumedActor.GetActor() == actor)
+ {
+ break;
+ }
interceptActorList.push_back(actor);
if(ShouldEmitInterceptTouchEvent(*actor, touchEvent))
{
{
Dali::Actor interceptedActor;
// Let's find out if there is an intercept actor.
- interceptedActor = EmitGeoInterceptTouchSignals(mCandidateActorLists, mInterceptedActorLists, touchEventHandle);
+ interceptedActor = EmitGeoInterceptTouchSignals(mCandidateActorLists, mInterceptedActorLists, touchEventHandle, mLastConsumedActor);
if(interceptedActor)
{
mInterceptedTouchActor.SetActor(&GetImplementation(interceptedActor));
/*
- * Copyright (c) 2023 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2024 Samsung Electronics Co., Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
uint32_t height,
uint32_t stride,
Pixel::Format pixelFormat,
- Dali::PixelData::ReleaseFunction releaseFunction)
+ Dali::PixelData::ReleaseFunction releaseFunction,
+ bool releaseAfterUpload)
: mBuffer(buffer),
mBufferSize(bufferSize),
mWidth(width),
mHeight(height),
mStride(stride),
mPixelFormat(pixelFormat),
- mReleaseFunction(releaseFunction)
+ mReleaseFunction(releaseFunction),
+ mReleaseAfterUpload(releaseAfterUpload)
{
DALI_LOG_INFO(gPixelDataLogFilter, Debug::Concise, "Allocated PixelData of size %u\n", bufferSize);
#if defined(DEBUG_ENABLED)
PixelData::~PixelData()
{
- if(mBuffer)
- {
- if(mReleaseFunction == Dali::PixelData::FREE)
- {
- free(mBuffer);
- }
- else
- {
- delete[] mBuffer;
- }
-#if defined(DEBUG_ENABLED)
- gPixelDataAllocationTotal -= mBufferSize;
-#endif
- }
+ ReleasePixelDataBuffer();
}
PixelDataPtr PixelData::New(uint8_t* buffer,
uint32_t height,
uint32_t stride,
Pixel::Format pixelFormat,
- Dali::PixelData::ReleaseFunction releaseFunction)
+ Dali::PixelData::ReleaseFunction releaseFunction,
+ bool releaseAfterUpload)
{
- return new PixelData(buffer, bufferSize, width, height, stride, pixelFormat, releaseFunction);
+ return new PixelData(buffer, bufferSize, width, height, stride, pixelFormat, releaseFunction, releaseAfterUpload);
}
uint32_t PixelData::GetWidth() const
return mBufferSize;
}
-Dali::Integration::PixelDataBuffer PixelData::ReleasePixelDataBuffer()
+void PixelData::ReleasePixelDataBuffer()
{
- Dali::Integration::PixelDataBuffer pixelDataBuffer(mBuffer, mBufferSize, mReleaseFunction);
- mBuffer = nullptr;
- return pixelDataBuffer;
+ if(mBuffer)
+ {
+ if(mReleaseFunction == Dali::PixelData::FREE)
+ {
+ free(mBuffer);
+ }
+ else
+ {
+ delete[] mBuffer;
+ }
+ mBuffer = nullptr;
+#if defined(DEBUG_ENABLED)
+ gPixelDataAllocationTotal -= mBufferSize;
+#endif
+ }
}
Dali::Integration::PixelDataBuffer PixelData::GetPixelDataBuffer() const
{
- Dali::Integration::PixelDataBuffer pixelDataBuffer(mBuffer, mBufferSize, mReleaseFunction);
+ Dali::Integration::PixelDataBuffer pixelDataBuffer(mBuffer, mBufferSize, mWidth, mHeight, mStride);
return pixelDataBuffer;
}
#define DALI_INTERNAL_PIXEL_DATA_H
/*
- * Copyright (c) 2023 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2024 Samsung Electronics Co., Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* @param [in] stride Buffer stride in pixels, 0 means the buffer is tightly packed
* @param [in] pixelFormat The pixel format
* @param [in] releaseFunction The function used to release the memory.
+ * @param [in] releaseAfterUpload Whether we release buffer after texture upload or not.
*/
static PixelDataPtr New(uint8_t* buffer,
uint32_t bufferSize,
uint32_t height,
uint32_t stride,
Pixel::Format pixelFormat,
- Dali::PixelData::ReleaseFunction releaseFunction);
+ Dali::PixelData::ReleaseFunction releaseFunction,
+ bool releaseAfterUpload);
/**
* @brief Constructor.
*
- * @param [in] buffer The raw pixel data.
- * @param [in] bufferSize The size of the buffer in bytes
- * @param [in] width Buffer width in pixels
- * @param [in] height Buffer height in pixels
- * @param [in] stride Buffer stride in pixels, 0 means the buffer is tightly packed
- * @param [in] pixelFormat The pixel format
- * @param [in] releaseFunction The function used to release the memory.
+ * @param [in] buffer The raw pixel data.
+ * @param [in] bufferSize The size of the buffer in bytes
+ * @param [in] width Buffer width in pixels
+ * @param [in] height Buffer height in pixels
+ * @param [in] stride Buffer stride in pixels, 0 means the buffer is tightly packed
+ * @param [in] pixelFormat The pixel format
+ * @param [in] releaseFunction The function used to release the memory.
+ * @param [in] releaseAfterUpload Whether we release buffer after texture upload or not.
*/
PixelData(uint8_t* buffer,
uint32_t bufferSize,
uint32_t height,
uint32_t stride,
Pixel::Format pixelFormat,
- Dali::PixelData::ReleaseFunction releaseFunction);
+ Dali::PixelData::ReleaseFunction releaseFunction,
+ bool releaseAfterUpload);
protected:
/**
uint32_t GetBufferSize() const;
/**
- * Return the buffer pointer and reset the internal buffer to zero.
- * @return The buffer pointer and associated data.
+ * Release the buffer data and reset the internal buffer to zero.
*/
- Dali::Integration::PixelDataBuffer ReleasePixelDataBuffer();
+ void ReleasePixelDataBuffer();
/**
* Return the buffer pointer.
Dali::Integration::PixelDataBuffer GetPixelDataBuffer() const;
/**
+ * Get whether we need to release pixel data after texture upload or not.
+ * @note This function can be called from another thread. Be careful.
+ * @return True if we need to release pixel data after texture upload. False otherwise.
+ */
+ bool IsPixelDataReleaseAfterUpload() const
+ {
+ return mReleaseAfterUpload;
+ }
+
+ /**
* @copydoc PixelData::GetStride()
*/
uint32_t GetStride() const;
Pixel::Format mPixelFormat; ///< Pixel format
Dali::PixelData::ReleaseFunction mReleaseFunction; ///< Function for releasing memory
+ const bool mReleaseAfterUpload;
+
#if defined(DEBUG_ENABLED)
static uint32_t gPixelDataAllocationTotal;
#endif
auto program = item.mRenderer->PrepareProgram(instruction);
if(program)
{
- auto memoryRequirements = program->GetUniformBlocksMemoryRequirements();
+ const auto& memoryRequirements = program->GetUniformBlocksMemoryRequirements();
totalSizeCPU += memoryRequirements.totalCpuSizeRequired;
totalSizeGPU += memoryRequirements.totalGpuSizeRequired;
/*
- * Copyright (c) 2021 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2024 Samsung Electronics Co., Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
#include <dali/internal/update/common/property-condition-step-functions.h>
#include <dali/public-api/common/dali-common.h>
+#include <dali/public-api/math/quaternion.h>
#include <dali/public-api/math/vector2.h>
#include <dali/public-api/math/vector3.h>
#include <dali/public-api/math/vector4.h>
const int32_t ARGINDEX_SECOND_VALUE = 4;
const int32_t ARGINDEX_THIRD_VALUE = 5;
+inline float AngleDifference(float a1, float a2, const float angleRangeHalf)
+{
+ float diff = fabs(a1 - a2);
+ return diff < angleRangeHalf ? diff : angleRangeHalf * 2.0f - diff;
+}
+
} // namespace
ConditionFunction Step::GetFunction(Property::Type valueType)
{
function = EvalAndCompareVector3;
}
+ else if(valueType == Property::ROTATION)
+ {
+ function = EvalAndCompareQuaternion;
+ }
else
{
function = GetFunction(valueType);
return Evaluate(propertyValue, arg);
}
+bool Step::EvalAndCompareQuaternion(const Dali::PropertyInput& value, PropertyNotification::RawArgumentContainer& arg)
+{
+ // TODO : Make some meaningfule calculation here
+
+ Quaternion propertyValue = value.GetQuaternion();
+
+ Vector4 v = propertyValue.EulerAngles();
+ const float checkValue = v.LengthSquared();
+ bool result = Evaluate(checkValue, arg);
+
+ if(result == false)
+ {
+ const float step = 1.0f / arg[ARGINDEX_STEP_SIZE];
+ if((AngleDifference(arg[ARGINDEX_FIRST_VALUE], v.x, Dali::Math::PI) > step) ||
+ (AngleDifference(arg[ARGINDEX_SECOND_VALUE], v.y, Dali::Math::PI_2) > step) ||
+ (AngleDifference(arg[ARGINDEX_THIRD_VALUE], v.z, Dali::Math::PI) > step))
+ {
+ result = true;
+ }
+ }
+ arg[ARGINDEX_FIRST_VALUE] = v.x;
+ arg[ARGINDEX_SECOND_VALUE] = v.y;
+ arg[ARGINDEX_THIRD_VALUE] = v.z;
+ return result;
+}
+
bool Step::EvalDefault(const Dali::PropertyInput& value, PropertyNotification::RawArgumentContainer& arg)
{
return false;
* Vector2 => 2 dimensional length of vector has stepped arg1 amount from arg0.
* Vector3 => 3 dimensional length of vector has stepped arg1 amount from arg0.
* Vector4 => 4 dimensional length of vector has stepped arg1 amount from arg0.
+ * Quaternion => 3 dimensional lenght of eular angle stepped arg1 amount from arg0
* Default => return false.
*/
class Step
static bool EvalVector4(const Dali::PropertyInput& value, PropertyNotification::RawArgumentContainer& arg);
/**
+ * Checks if Quaternion is Outside
+ *
+ * If previous Quaternion and current examined value are same, the raw datas are checked with comparing these values.
+ *
+ * @param[in] value The value being examined.
+ * @param[in] arg The supplied arguments for the condition.
+ * @return Condition result (true if condition met, false if not)
+ */
+ static bool EvalAndCompareQuaternion(const Dali::PropertyInput& value, PropertyNotification::RawArgumentContainer& arg);
+
+ /**
* Default check for other types.
* @param[in] value The value being examined.
* @param[in] arg The supplied arguments for the condition.
{
const uint32_t CORE_MAJOR_VERSION = 2;
const uint32_t CORE_MINOR_VERSION = 3;
-const uint32_t CORE_MICRO_VERSION = 5;
+const uint32_t CORE_MICRO_VERSION = 6;
const char* const CORE_BUILD_DATE = __DATE__ " " __TIME__;
#ifdef DEBUG_ENABLED
return GetImplementation(*this).GetAttachedActor(index);
}
+bool GestureDetector::FeedTouch(Dali::Actor& actor, Dali::TouchEvent& touch)
+{
+ return GetImplementation(*this).FeedTouch(actor, touch);
+}
+
} // namespace Dali
// INTERNAL INCLUDES
#include <dali/public-api/object/handle.h>
+#include <dali/public-api/events/touch-event.h>
namespace Dali
{
*/
Actor GetAttachedActor(size_t index) const;
+ /**
+ * @brief The gesture is recognized by sending a Touch event to the actor.
+ *
+ * @param actor The actor receiving touch events
+ * @param touch The thouch event
+ * @return If true , the gesture is being recognized.
+ */
+ bool FeedTouch(Dali::Actor& actor, Dali::TouchEvent& touch);
+
protected:
/// @cond internal
/**
/*
- * Copyright (c) 2022 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2024 Samsung Electronics Co., Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
Pixel::Format pixelFormat,
ReleaseFunction releaseFunction)
{
- IntrusivePtr<Internal::PixelData> internal = Internal::PixelData::New(buffer, bufferSize, width, height, 0, pixelFormat, releaseFunction);
+ IntrusivePtr<Internal::PixelData> internal = Internal::PixelData::New(buffer, bufferSize, width, height, 0, pixelFormat, releaseFunction, false);
return PixelData(internal.Get());
}
Pixel::Format pixelFormat,
ReleaseFunction releaseFunction)
{
- IntrusivePtr<Internal::PixelData> internal = Internal::PixelData::New(buffer, bufferSize, width, height, stride, pixelFormat, releaseFunction);
+ IntrusivePtr<Internal::PixelData> internal = Internal::PixelData::New(buffer, bufferSize, width, height, stride, pixelFormat, releaseFunction, false);
return PixelData(internal.Get());
}
* vector2 (the 2D length)
* vector3 (the 3D length)
* vector4 (the 4D length)
+ * quaternion (the 3D length of eular angle)
* @SINCE_1_0.0
* @param[in] stepAmount The step size required to trigger condition
* @param[in] initialValue The initial value to step from
Name: dali2
Summary: DALi 3D Engine
-Version: 2.3.5
+Version: 2.3.6
Release: 1
Group: System/Libraries
License: Apache-2.0 and BSD-3-Clause and MIT